外观
项目介绍
项目结构
Admin.Core 8.5.0
Admin.Core
├── 01.sln // 项目文件
│ └── Directory.Build.props // 指定 Target Framework 和 Nuget 包版本
├── 02.build // 打包构建
│ └── Directory.Build.props // Nuget包属性
├── modules // 模块项目
│ └── admin // 权限管理
│ ├── ZhonTai.Host // 接口启动项目
│ │ ├── ConfigCenter // 配置中心文件
│ │ ├── InitData // 初始化数据
│ │ ├── appsettings.json // 系统应用配置
│ │ └── nlog.config // nlog日志配置
│ ├── ZhonTai.Admin // 权限接口项目
│ │ ├── Core // 接口核心
│ │ ├── Domain // 领域:实体、仓储接口、Dto定义
│ │ ├── Repositories // 仓储实现
│ │ ├── Services // 服务接口、服务实现、Dto定义
│ │ └── Tools // 辅助工具/第三方Nuget包封装
│ └── ZhonTai.Tests // 权限测试项目
│ ├── Controllers // 接口测试
│ ├── Repositories // 仓储测试
│ └── Services // 服务测试
└── platform // 平台项目
├── ZhonTai.ApiUI // 接口文档库
├── ZhonTai.Common // 通用帮助库
└── ZhonTai.DynamicApi // 动态接口库
Admin模板 8.5.0
用模板新建项目MyCompanyName.MyProjectName,文件结构如下:
MyCompanyName.MyProjectName
├── MyCompanyName.MyProjectName.Host // 启动项目
│ ├── ConfigCenter // 配置中心文件
│ ├── InitData // 初始化数据
│ ├── appsettings.json // 系统应用配置
│ └── nlog.config // nlog日志配置
├── MMyCompanyName.MyProjectName.Api // 接口项目
│ ├── Core // 接口核心
│ ├── Domain // 领域:实体、仓储接口定义
│ ├── Repositories // 仓储实现
│ └── Services // 服务接口、服务实现、输入输出模型定义
├── MMyCompanyName.MyProjectName.Api.Contracts // 契约项目
│ ├── Resources // 国际化资源文件
│ └── Services // 服务接口、输入输出模型定义
└── MyCompanyName.MyProjectName.Tests // 测试项目
├── Controllers // 接口测试
├── Repositories // 仓储测试
└── Services // 服务测试
配置文件
appsettings.json 应用程序配置
appsettings.json
json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.Extensions.Diagnostics.HealthChecks": "Warning"
}
},
"AllowedHosts": "*",
//应用配置
"AppSettings": {
//使用配置中心
"UseConfigCenter": true,
//配置中心路径
"ConfigCenterPath": "ConfigCenter"
},
// 事件总线和分布式事务
"CAP": {
"RabbitMq": {
"HostName": "",
"Port": 5672,
"UserName": "",
"Password": ""
}
},
/*
//发送邮件验证码
await AppInfo.GetRequiredService<ICapPublisher>().PublishAsync(SubscribeNames.EmailSingleSend,
new EamilSingleSendEvent
{
ToEmail = new EamilSingleSendEvent.Models.EmailModel
{
Address = ""
},
Subject = "中台Admin账号邮件验证码",
Body = code
});
*/
//邮件配置
"Email": {
//主机
"Host": "smtp.qq.com",
//端口 465、587、25
"Port": 465,
//是否使用SSL
"UseSsl": true,
//邮箱账号
"UserName": "",
//邮箱密码
"Password": "",
//发件人
"FromEmail": {
//名称
"Name": "",
//地址
"Address": ""
},
//收件人
"ToEmail": {
//名称
"Name": "",
//地址
"Address": ""
}
},
//任务调度配置
"TaskScheduler": {
//进程启动信息
"ProcessStartInfo": {
"FileName": "C:/grpcurl_1.8.7/grpcurl",
//工作目录
"WorkingDirectory": ""
},
//告警邮件
"AlerEmail": {
"Enable": true,
"Adress": ""
}
},
// 滑动验证码
"SlideCaptcha": {
// 缓存过期时长
"ExpirySeconds": 300,
// 缓存前缀
"StoreageKeyPrefix": "app:captcha:",
// 容错值(校验时用,缺口位置与实际滑动位置匹配容错范围)
"Tolerant": 0.02,
// 背景图配置
"Backgrounds": [
{
"Type": "file",
"Data": "wwwroot/captcha/jigsaw/backgrounds/1.jpg"
},
{
"Type": "file",
"Data": "wwwroot/captcha/jigsaw/backgrounds/2.jpg"
},
{
"Type": "file",
"Data": "wwwroot/captcha/jigsaw/backgrounds/3.jpg"
},
{
"Type": "file",
"Data": "wwwroot/captcha/jigsaw/backgrounds/4.jpg"
},
{
"Type": "file",
"Data": "wwwroot/captcha/jigsaw/backgrounds/5.jpg"
}
],
// Templates不配置,则使用默认模板
"Templates": [
//{
// "Slider": {
// "Type": "file",
// "Data": "wwwroot/captcha/jigsaw/templates/1/transparent.png"
// },
// "Hole": {
// "Type": "file",
// "Data": "wwwroot/captcha/jigsaw/templates/1/dark.png"
// }
//}
]
}
}
dbconfig.json 数据库配置
dbconfig.json
json
{
"DbConfig": {
//数据库注册键
"key": "appdb",
//程序集名称,自动获取实体表,为空则通过ConfigureFreeSql自定义配置
"assemblyNames": [ "MyCompanyName.MyProjectName.Api" ],
//监听所有操作
"monitorCommand": false,
//监听Curd操作
"curd": true,
//监听同步结构脚本
"syncStructureSql": false,
//监听同步数据Curd操作
"syncDataCurd": false,
//建库
"createDb": false,
//SqlServer,PostgreSQL,Oracle,OdbcOracle,OdbcSqlServer,OdbcMySql,OdbcPostgreSQL,Odbc,OdbcDameng,MsAccess
//建库连接字符串
//MySql "Server=localhost; Port=3306; Database=mysql; Uid=root; Pwd=pwd; Charset=utf8mb4;"
//SqlServer "Data Source=.;User Id=sa;Password=pwd;Initial Catalog=master;TrustServerCertificate=true;Pooling=true;Min Pool Size=1"
//PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=postgres;Pooling=true;Minimum Pool Size=1"
//Oracle "user id=SYS;password=pwd; data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1"
"createDbConnectionString": "",
//建库脚本,复杂建库脚本可放到createdbsql.txt中
//MySql "CREATE DATABASE `appdb` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'"
//SqlServer "CREATE DATABASE [appdb]"
//PostgreSQL "CREATE DATABASE \"appdb\" WITH ENCODING = 'UTF8'"
"createDbSql": "",
//同步结构
"syncStructure": true,
//同步结构批次实体数
"syncStructureEntityBatchSize": 1,
//同步数据
"syncData": true,
//同步更新数据
"sysUpdateData": true,
//新增强制更新EntityUpdate数据
"forceUpdate": false,
//同步数据地址
//"SyncDataPath": "InitData/Admin",
//同步所有表["ad_dict_type", "ad_dict", "ad_user", "ad_user_staff", "ad_org", "ad_role", "ad_api", "ad_view", "ad_permission", "ad_permission_api", "ad_user_role", "ad_user_org", "ad_role_permission", "ad_tenant", "ad_tenant_permission"]
//同步指定表["ad_api", "ad_view", "ad_permission", "ad_permission_api"]
//同步数据包含表,指定表同步,不填同步所有表
"syncDataIncludeTables": [],
//同步排除表["ad_user"]
//同步数据排除表,指定表不同步
"syncDataExcludeTables": [],
//同步数据操作用户
"syncDataUser": {
"id": 161223411986501,
"userName": "admin",
"name": "管理员",
"tenantId": 161223412138053
},
//项目初始化不开启生成数据,发布生产环境前,如果开发环境有配置数据需要更新数据包,可以开启生成数据包,使用完记得关闭
//开启生成数据前先关闭syncStructure syncData createDb
//生成数据
"generateData": false,
//数据库配置 https://github.com/dotnetcore/FreeSql/wiki/入门
//连接字符串语法 https://www.connectionstrings.com
//数据库类型 MySql = 0, SqlServer = 1, PostgreSQL = 2, Oracle = 3, Sqlite = 4, OdbcOracle = 5, OdbcSqlServer = 6, OdbcMySql = 7, OdbcPostgreSQL = 8, Odbc = 9, OdbcDameng = 10, MsAccess = 11, Dameng = 12, OdbcKingbaseES = 13, ShenTong = 14, KingbaseES = 15, Firebird = 16
"type": "Sqlite",
//连接字符串
//MySql "Server=localhost; Port=3306; Database=appdb; Uid=root; Pwd=pwd; Charset=utf8mb4;"
//SqlServer "Data Source=.;Integrated Security=True;Initial Catalog=appdb;Pooling=true;Min Pool Size=1"
//PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=appdb;Pooling=true;Minimum Pool Size=1"
//Sqlite "Data Source=|DataDirectory|\\appdb.db; Pooling=true;Min Pool Size=1"
//"Oracle" "user id=SYS;password=pwd; data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1",
"connectionString": "Data Source=|DataDirectory|\\appdb.db; Pooling=true;Min Pool Size=1",
//指定程序集
//FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector
"providerType": "",
//读写分离从库列表
"slaveList": [
//{
// //权重
// "Weight": 1,
// //连接字符串
// "ConnectionString": "Data Source=|DataDirectory|\\appdb.db; Pooling=true;Min Pool Size=1"
//}
],
//空闲时间(分),设置idleTime=0则不自动回收, 设置1天不使用则自动回收
"idleTime": 1440,
//新增时强制更新EntityUpdate数据
"forceUpdate": false,
//多数据库
//Core/Consts定义DbKeys枚举
//使用仓储访问 public ModuleRepository(UnitOfWorkManagerCloud muowm) : base(DbKeys.AppDb, muowm)
//使用FreeSqlCloud访问 freeSqlCloud.Use(DbKeys.AppDb);
"dbs": [
{
//权限库
"key": "admindb",
//程序集名称,自动获取实体表
"assemblyNames": [ "ZhonTai.Admin" ],
//监听所有操作
"monitorCommand": false,
//监听Curd操作
"curd": true,
//建库
"createDb": false,
//SqlServer,PostgreSQL,Oracle,OdbcOracle,OdbcSqlServer,OdbcMySql,OdbcPostgreSQL,Odbc,OdbcDameng,MsAccess
//建库连接字符串
//MySql "Server=localhost; Port=3306; Database=mysql; Uid=root; Pwd=pwd; Charset=utf8mb4;"
//SqlServer "Data Source=.;User Id=sa;Password=pwd;Initial Catalog=master;TrustServerCertificate=true;Pooling=true;Min Pool Size=1"
//PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=postgres;Pooling=true;Minimum Pool Size=1"
//Oracle "user id=SYS;password=pwd; data source=127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1"
"createDbConnectionString": "",
//建库脚本,复杂建库脚本可放到createdbsql.txt中
//MySql "CREATE DATABASE `admindb` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'"
//SqlServer "CREATE DATABASE [admindb]"
//PostgreSQL "CREATE DATABASE \"admindb\" WITH ENCODING = 'UTF8'"
"createDbSql": "",
//同步结构
"syncStructure": true,
//同步数据
"syncData": true,
//项目初始化不开启生成数据,发布生产环境前,如果开发环境有配置数据需要更新数据包,可以开启生成数据包,使用完记得关闭
//开启生成数据前先关闭syncStructure syncData createDb
//生成数据
"generateData": false,
//数据库配置 https:github.com/dotnetcore/FreeSql/wiki/入门
//连接字符串语法 https:www.connectionstrings.com
//数据库类型 MySql = 0, SqlServer = 1, PostgreSQL = 2, Oracle = 3, Sqlite = 4, OdbcOracle = 5, OdbcSqlServer = 6, OdbcMySql = 7, OdbcPostgreSQL = 8, Odbc = 9, OdbcDameng = 10, MsAccess = 11, Dameng = 12, OdbcKingbaseES = 13, ShenTong = 14, KingbaseES = 15, Firebird = 16
"type": "Sqlite",
//连接字符串
//MySql "Server=localhost; Port=3306; Database=admindb; Uid=root; Pwd=pwd; Charset=utf8mb4;"
//SqlServer "Data Source=.;Integrated Security=True;Initial Catalog=admindb;Pooling=true;Min Pool Size=1"
//PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=admindb;Pooling=true;Minimum Pool Size=1"
//Sqlite "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1"
//"Oracle" "user id=SYS;password=pwd; data source=127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1",
"connectionString": "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1",
//指定程序集
//FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector
"providerType": "",
//读写分离从库列表
"slaveList": [
//{
// 权重
// "Weight": 1,
// 连接字符串
// "ConnectionString": "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1"
//}
]
}
]
}
}
appconfig.json 自定义应用配置 8.5.0
appconfig.json
json
{
"AppConfig": {
//应用程序类型Controllers ControllersWithViews MVC
"appType": "Controllers",
//Api地址
"urls": [ "http://*:8000" ],
//跨域地址
"corUrls": [],
//程序集名称
"assemblyNames": [ "MyCompanyName.MyProjectName.Api", "ZhonTai.Admin" ],
//租户
"tenant": true,
//分布式事务唯一标识app,为空则不生成分布式事务表
"distributeKey": "",
//验证
"validate": {
//登录
"login": true,
//权限
"permission": true,
//数据权限
"dataPermission": true,
//接口数据权限
"apiDataPermission": true
},
//Swagger接口文档,访问路径/swagger
"swagger": {
//启用
"enable": true,
//启用枚举架构过滤器
"enableEnumSchemaFilter": true,
//启用接口排序文档过滤器
"enableOrderTagsDocumentFilter": true,
//启用枚举属性名
"enableJsonStringEnumConverter": false,
//启用SchemaId命名空间
"enableSchemaIdNamespace": false,
//程序集列表,用于启用SchemaId命名空间
"assemblyNameList": [],
//路由前缀,如配置微服务文档地址:doc/module/swagger
"routePrefix": "app/swagger",
//地址
"url": "http://localhost:8000",
//项目列表
"projects": [
{
"name": "MyCompanyName.MyProjectName",
"code": "app",
"version": "v8.3.0",
"description": "MyCompanyName.MyProjectName"
}
,
{
"name": "中台Admin",
"code": "admin",
"version": "v8.3.0",
"description": "权限管理"
}
]
},
//新版接口文档展示
"apiUI": {
//启用
"enable": true,
//路由前缀,如配置微服务文档地址:doc/module
"routePrefix": "app",
//页脚
"footer": {
"enable": false,
"content": "Copyright<a-icon type=\"copyright\" /> 2022-<a target=\"_blank\" href=\"https://www.zhontai.net\">中台Admin</a>"
}
},
//MiniProfiler性能分析器
"miniProfiler": false,
//统一认证授权服务器
"identityServer": {
//启用
"enable": false,
//地址,开发认证地址前往appconfig.Development.json修改
"url": "https://localhost:5000",
//启用Https
"requireHttpsMetadata": true,
//订阅者
"audience": "admin.server.api"
},
//面向切面编程
"aop": {
//事物
"transaction": true
},
//日志
"log": {
//操作日志
"operation": true
},
//限流
"rateLimit": false,
//验证码
"varifyCode": {
//启用
"enable": true,
//字体列表
"fonts": [ "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" ]
},
//默认密码
"defaultPassword": "123asd",
//动态api
"dynamicApi": {
//结果格式化
"formatResult": true
},
//实现标准标识密码哈希
"passwordHasher": false,
//Kestrel服务器配置
"Kestrel": {
//HTTP连接保活最长时间,单位秒,600 = 10 分钟
"KeepAliveTimeout": 600,
//发送请求头最长时间,单位秒,600 = 10 分钟
"RequestHeadersTimeout": 600,
//最大请求大小,单位 bytes, 设置 null 不限制大小,104857600 = 100 MB
"maxRequestBodySize": 104857600
},
//健康检查
"healthChecks": {
//启用
"enable": true,
//访问路径
"path": "/app/health"
},
//指定跨域访问时预检等待时间,以秒为单位,默认30分钟
"PreflightMaxAge": 1800,
//是否开启任务调度管理界面
"TaskSchedulerUI": {
//启用
"enable": true,
//访问路径
"path": "/task"
},
//Id生成器
"IdGenerator": {
"DataCenterId": 0, // 数据中心ID(机房ID,默认0) 请确保全局唯一
"WorkerId": 1, // 机器码,必须全局唯一(或相同 DataCenterId 内唯一),理论最大值 2^WorkerIdBitLength-1 = 63,最大值 524287
"WorkerIdBitLength": 6, // 机器码位长,决定 WorkerId 的最大值,默认值6,取值范围 [1, 19]
"SeqBitLength": 6, // 序列数位长,默认值6,取值范围 [3, 21],决定每毫秒基础生成的ID个数。如果每秒请求数不超过5W,保持默认值6即可;如果超过5W,不超过50W,建议赋值10或更大,以此类推。
"CachePrefix": "zhontai:workerid" // 缓存前缀
},
//语言配置
"Lang": {
//启用Json配置
"EnableJson": true,
//默认语言
"DefaultLang": "zh-CN",
//语言列表
"Langs": [ "zh-CN", "en" ],
//语言请求解析列表
"RequestCultureProviders": [] //["QueryString","Cookie","AcceptLanguageHeader"]
},
//IP地址定位
"IP2Region": {
//启用
"Enable": true,
//绝对数据库路径,为空则默认使用网站根目录/ip2region.xdb
"DbPath": ""
}
}
}
cacheconfig.json 缓存配置
cacheconfig.json
json
{
"CacheConfig": {
//缓存类型 Memory = 0,Redis = 1
"type": "Memory",
//限流缓存类型 Memory = 0,Redis = 1
"typeRateLimit": "Memory",
//Redis配置
"redis": {
//连接字符串
"connectionString": "127.0.0.1:6379,password=,defaultDatabase=0",
//限流连接字符串
"connectionStringRateLimit": "127.0.0.1:6379,password=,defaultDatabase=0"
}
}
}
jwtconfig.json Jwt配置
jwtconfig.json
json
{
"JwtConfig": {
//发行者
"issuer": "admin.core",
//订阅者
"audience": "admin.core",
//密钥
"securityKey": "73c50ca4f5e411eda7095254008978e98978e9edada7095254070952540089",
//有效期(分钟) 120 = 2小时
"expires": 120,
//刷新有效期(分钟) 1440 = 1天
"refreshExpires": 1440
}
}
ossconfig.json OSS文件上传配置
ossconfig.json
json
{
"OssConfig": {
//本地上传配置
"LocalUploadConfig": {
//上传目录
"Directory": "upload",
//日期目录
"DateTimeDirectory": "yyyy/MM/dd",
"Md5": false,
//文件最大大小byte
"MaxSize": 104857600,
//包含文件拓展名
"IncludeExtension": [],
//排除文件拓展名
"ExcludeExtension": [ ".exe", ".dll", ".jar" ]
},
//文件存储供应商
"Provider": "Minio",
//OSS配置列表
"OSSConfigs": [
//Minio
{
"Provider": "Minio",
"Endpoint": "127.0.0.1:9006",
"Region": "",
"AccessKey": "minio",
"SecretKey": "minio",
"IsEnableHttps": false,
"IsEnableCache": true,
"BucketName": "admin",
"Url": "", //文件外链
"Md5": false,
"Enable": false
},
//阿里云
{
"Provider": "Aliyun",
"Endpoint": "oss-cn-shenzhen.aliyuncs.com",
"Region": "",
"AccessKey": "",
"SecretKey": "",
"IsEnableHttps": true,
"IsEnableCache": true,
"BucketName": "admin",
"Url": "",
"Md5": false,
"Enable": false
},
//腾讯云
{
"Provider": "QCloud",
"Endpoint": "", //AppId
"Region": "",
"AccessKey": "",
"SecretKey": "",
"IsEnableHttps": true,
"IsEnableCache": true,
"BucketName": "admin",
"Url": "",
"Md5": false,
"Enable": false
},
//七牛
{
"Provider": "Qiniu",
"Endpoint": "",
"Region": "",
"AccessKey": "",
"SecretKey": "",
"IsEnableHttps": true,
"IsEnableCache": true,
"BucketName": "admin",
"Url": "",
"Md5": false,
"Enable": false
},
//华为云
{
"Provider": "HuaweiCloud",
"Endpoint": "",
"Region": "",
"AccessKey": "",
"SecretKey": "",
"IsEnableHttps": true,
"IsEnableCache": true,
"BucketName": "admin",
"Url": "",
"Md5": false,
"Enable": false
}
]
}
}
ratelimitconfig.json 限流配置
ratelimitconfig.json
json
{
/*
https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware
https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/Using-Redis-as-a-distributed-counter-store
*/
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"IpWhitelist": [], // "127.0.0.1"
"EndpointWhitelist": [ "get:/api/admin/auth/refresh" ], // "get:/api/a", "*:/api/b"
"ClientWhitelist": [],
"HttpStatusCode": 429,
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁!\"}}",
"ContentType": "application/json",
"StatusCode": 429
},
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 3
},
{
"Endpoint": "*",
"Period": "10m",
"Limit": 200
}
]
}
}