mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 18:51:28 +08:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -373,3 +373,4 @@ FodyWeavers.xsd
|
||||
/src/nupkgs/
|
||||
/src/nupkgs
|
||||
|
||||
/src/.idea/
|
||||
|
@@ -1,86 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://kimdiego2098.github.io/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using ThingsGateway.Logging;
|
||||
|
||||
using UAParser;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
[AppStartup(-99999)]
|
||||
public class AdminStartup : AppStartup
|
||||
{
|
||||
public void ConfigBlazorServer(IServiceCollection services)
|
||||
{
|
||||
|
||||
|
||||
#region api日志
|
||||
|
||||
//Monitor日志配置
|
||||
services.AddMonitorLogging(options =>
|
||||
{
|
||||
options.JsonIndented = true;// 是否美化 JSON
|
||||
options.GlobalEnabled = false;//全局启用
|
||||
options.ConfigureLogger((logger, logContext, context) =>
|
||||
{
|
||||
var httpContext = context.HttpContext;//获取httpContext
|
||||
//获取头
|
||||
var userAgent = httpContext.Request.Headers["User-Agent"];
|
||||
if (string.IsNullOrEmpty(userAgent)) userAgent = "Other";//如果没有这个头就指定一个
|
||||
|
||||
var parser = Parser.GetDefault();
|
||||
//获取客户端信息
|
||||
var client = parser.Parse(userAgent);
|
||||
// 获取控制器/操作描述器
|
||||
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
|
||||
//操作名称默认是控制器名加方法名,自定义操作名称要在action上加Description特性
|
||||
var option = $"{controllerActionDescriptor.ControllerName}/{controllerActionDescriptor.ActionName}";
|
||||
|
||||
var desc = NetCoreApp.CreateLocalizerByType(controllerActionDescriptor.ControllerTypeInfo.AsType())[controllerActionDescriptor.MethodInfo.Name];
|
||||
//获取特性
|
||||
option = desc.Value;//则将操作名称赋值为控制器上写的title
|
||||
|
||||
logContext.Set(LoggingConst.CateGory, option);//传操作名称
|
||||
logContext.Set(LoggingConst.Operation, option);//传操作名称
|
||||
logContext.Set(LoggingConst.Client, client);//客户端信息
|
||||
logContext.Set(LoggingConst.Path, httpContext.Request.Path.Value);//请求地址
|
||||
logContext.Set(LoggingConst.Method, httpContext.Request.Method);//请求方法
|
||||
});
|
||||
});
|
||||
//日志写入数据库配置
|
||||
services.AddDatabaseLogging<DatabaseLoggingWriter>(options =>
|
||||
{
|
||||
options.WriteFilter = (logMsg) =>
|
||||
{
|
||||
return logMsg.LogName == "System.Logging.LoggingMonitor";//只写入LoggingMonitor日志
|
||||
};
|
||||
});
|
||||
|
||||
#endregion api日志
|
||||
|
||||
|
||||
services.AddSingleton<IUnifyResultProvider, UnifyResultProvider>();
|
||||
services.AddSingleton<IAuthService, AuthService>();
|
||||
services.AddScoped<IAuthRazorService, AuthRazorService>();
|
||||
services.AddSingleton<IAppService, AspNetCoreAppService>();
|
||||
services.AddSingleton<IApiPermissionService, ApiPermissionService>();
|
||||
|
||||
services.AddSingleton<IFileService, FileService>();
|
||||
services.AddSingleton<IImportExportService, ImportExportService>();
|
||||
|
||||
services.AddSingleton<ISignalrNoticeService, SignalrNoticeService>();
|
||||
services.AddSingleton<IAuthService, AuthService>();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -3,12 +3,6 @@
|
||||
|
||||
|
||||
|
||||
"ThingsGateway.Admin.Application.FileService": {
|
||||
"FileNullError": "File cannot be empty",
|
||||
"FileLengthError": "File size cannot exceed {0} M",
|
||||
"FileTypeError": "Not supported format {0}"
|
||||
},
|
||||
|
||||
//controller
|
||||
"ThingsGateway.Admin.Application.AuthController": {
|
||||
//auth
|
||||
@@ -28,6 +22,14 @@
|
||||
"LogoutAsync": "Logout"
|
||||
},
|
||||
|
||||
|
||||
|
||||
"ThingsGateway.Admin.Application.FileService": {
|
||||
"FileNullError": "File cannot be empty",
|
||||
"FileLengthError": "File size cannot exceed {0} M",
|
||||
"FileTypeError": "Not supported format {0}"
|
||||
},
|
||||
|
||||
"ThingsGateway.Admin.Application.UnifyResultProvider": {
|
||||
"TokenOver": "Login has expired, please login again",
|
||||
"NoPermission": "Access denied, no permission"
|
||||
|
@@ -1,14 +1,6 @@
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
"ThingsGateway.Admin.Application.FileService": {
|
||||
"FileNullError": "文件不能为空",
|
||||
"FileLengthError": "文件大小不允许超过 {0} M",
|
||||
"FileTypeError": "不支持 {0} 格式"
|
||||
},
|
||||
|
||||
//controller
|
||||
"ThingsGateway.Admin.Application.AuthController": {
|
||||
//auth
|
||||
@@ -28,6 +20,16 @@
|
||||
"LogoutAsync": "注销"
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"ThingsGateway.Admin.Application.FileService": {
|
||||
"FileNullError": "文件不能为空",
|
||||
"FileLengthError": "文件大小不允许超过 {0} M",
|
||||
"FileTypeError": "不支持 {0} 格式"
|
||||
},
|
||||
|
||||
"ThingsGateway.Admin.Application.UnifyResultProvider": {
|
||||
"TokenOver": "登录已过期,请重新登录",
|
||||
"NoPermission": "禁止访问,没有权限"
|
||||
@@ -39,7 +41,8 @@
|
||||
"PasswordError": "密码错误次数过多,请 {0} 分钟后再试",
|
||||
"AuthErrorMax": "账号密码错误,超过 {0} 次后将锁定 {1} 分钟,错误次数 {2} ",
|
||||
"UserDisable": "账号 {0} 已停用",
|
||||
"MustDesc": "密码需要DESC加密后传入"
|
||||
"MustDesc": "密码需要DESC加密后传入",
|
||||
"UserNoModule": "该账号未分配模块,请联系管理员"
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -137,7 +137,6 @@
|
||||
"CanotDeleteSelf": "不可删除自己",
|
||||
"EmailError": "邮箱 {0} 格式错误",
|
||||
"PhoneError": "手机号码 {0} 格式错误",
|
||||
"UserNoModule": "该账号未分配模块,请联系管理员",
|
||||
|
||||
"DemoCanotUpdatePassword": "DEMO环境不允许修改密码",
|
||||
"OldPasswordError": "原密码错误",
|
||||
|
23
src/ThingsGateway.Admin.NetCore/Locales/en-US.json
Normal file
23
src/ThingsGateway.Admin.NetCore/Locales/en-US.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
|
||||
"ThingsGateway.Admin.Application.FileService": {
|
||||
"FileNullError": "File cannot be empty",
|
||||
"FileLengthError": "File size cannot exceed {0} M",
|
||||
"FileTypeError": "Not supported format {0}"
|
||||
},
|
||||
|
||||
"ThingsGateway.Admin.Application.UnifyResultProvider": {
|
||||
"TokenOver": "Login has expired, please login again",
|
||||
"NoPermission": "Access denied, no permission"
|
||||
},
|
||||
|
||||
"ThingsGateway.Admin.Application.AuthService": {
|
||||
"SingleLoginWarn": "Your account is logged in elsewhere",
|
||||
"UserNull": "User {0} does not exist",
|
||||
"MustDesc": "Password needs to be encrypted with DESC before passing",
|
||||
"PasswordError": "Too many password errors, please try again in {0} minutes",
|
||||
"UserDisable": "Account {0} has been disabled",
|
||||
"UserNoModule": "This account has not been assigned a module. Please contact the administrator",
|
||||
"AuthErrorMax": "Account password error, will be locked for {1} minutes after exceeding {0} times, error count {2}"
|
||||
}
|
||||
}
|
24
src/ThingsGateway.Admin.NetCore/Locales/zh-CN.json
Normal file
24
src/ThingsGateway.Admin.NetCore/Locales/zh-CN.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
|
||||
"ThingsGateway.Admin.Application.FileService": {
|
||||
"FileNullError": "文件不能为空",
|
||||
"FileLengthError": "文件大小不允许超过 {0} M",
|
||||
"FileTypeError": "不支持 {0} 格式"
|
||||
},
|
||||
|
||||
"ThingsGateway.Admin.Application.UnifyResultProvider": {
|
||||
"TokenOver": "登录已过期,请重新登录",
|
||||
"NoPermission": "禁止访问,没有权限"
|
||||
},
|
||||
|
||||
"ThingsGateway.Admin.Application.AuthService": {
|
||||
"SingleLoginWarn": "您的账号已在别处登录",
|
||||
"UserNull": "用户 {0} 不存在",
|
||||
"PasswordError": "密码错误次数过多,请 {0} 分钟后再试",
|
||||
"AuthErrorMax": "账号密码错误,超过 {0} 次后将锁定 {1} 分钟,错误次数 {2} ",
|
||||
"UserDisable": "账号 {0} 已停用",
|
||||
"MustDesc": "密码需要DESC加密后传入",
|
||||
"UserNoModule": "该账号未分配模块,请联系管理员"
|
||||
}
|
||||
|
||||
}
|
@@ -2,9 +2,17 @@
|
||||
<Import Project="$(SolutionDir)Version.props" />
|
||||
<Import Project="$(SolutionDir)PackNuget.props" />
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(SolutionDir)\ThingsGateway.Admin.Application\ThingsGateway.Admin.Application.csproj" />
|
||||
<ProjectReference Include="..\ThingsGateway.Admin.Razor\ThingsGateway.Admin.Razor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="Locales\*.json" />
|
||||
<EmbeddedResource Include="Locales\*.json">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,25 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://kimdiego2098.github.io/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
[AppStartup(-99999)]
|
||||
public class GatewayStartup : AppStartup
|
||||
{
|
||||
public void ConfigBlazorServer(IServiceCollection services)
|
||||
{
|
||||
|
||||
services.AddScoped<ThingsGateway.Gateway.Application.IGatewayExportService, GatewayExportService>();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -68,7 +68,6 @@ public class ChannelThread
|
||||
|
||||
private static async Task SetCycleInterval()
|
||||
{
|
||||
var db = DbContext.Db.GetConnectionScopeWithAttr<SysOperateLog>().CopyNew();
|
||||
var appLifetime = NetCoreApp.RootServices!.GetService<IHostApplicationLifetime>()!;
|
||||
|
||||
var hardwareInfoService = HostedServiceUtil.GetHostedService<HardwareInfoService>();
|
||||
|
@@ -28,6 +28,8 @@ public class GatewayExportService : IGatewayExportService
|
||||
|
||||
public async Task OnChannelExport(QueryPageOptions options)
|
||||
{
|
||||
options.IsPage = false;
|
||||
options.IsVirtualScroll = false;
|
||||
var service = NetCoreApp.RootServices.GetRequiredService<IChannelService>();
|
||||
var data = await service.PageAsync(options);
|
||||
if (data.Items.Count() > 0)
|
||||
@@ -39,6 +41,8 @@ public class GatewayExportService : IGatewayExportService
|
||||
|
||||
public async Task OnDeviceExport(QueryPageOptions options, bool collect)
|
||||
{
|
||||
options.IsPage = false;
|
||||
options.IsVirtualScroll = false;
|
||||
var service = NetCoreApp.RootServices.GetRequiredService<IDeviceService>();
|
||||
var data = await service.PageAsync(options, collect ? PluginTypeEnum.Collect : PluginTypeEnum.Business);
|
||||
if (data.Items.Count() > 0)
|
||||
@@ -51,6 +55,8 @@ public class GatewayExportService : IGatewayExportService
|
||||
|
||||
public async Task OnVariableExport(QueryPageOptions options)
|
||||
{
|
||||
options.IsPage = false;
|
||||
options.IsVirtualScroll = false;
|
||||
var service = NetCoreApp.RootServices.GetRequiredService<IVariableService>();
|
||||
var data = await service.PageAsync(options);
|
||||
if (data.Items.Count() > 0)
|
||||
|
@@ -50,11 +50,9 @@ public class SingleFilePublish : ISingleFilePublish
|
||||
"ThingsGateway.Razor",
|
||||
"ThingsGateway.Gateway.Application",
|
||||
"ThingsGateway.Gateway.Razor" ,
|
||||
"ThingsGateway.Gateway.ASPNetCore" ,
|
||||
"ThingsGateway.Gateway.NetCore" ,
|
||||
"ThingsGateway.Admin.Razor" ,
|
||||
"ThingsGateway.Admin.Application" ,
|
||||
"ThingsGateway.Admin.ASPNetCore" ,
|
||||
"ThingsGateway.Admin.NetCore" ,
|
||||
"SqlSugar.TDengineCore",
|
||||
];
|
||||
|
@@ -51,11 +51,9 @@ public class SingleFilePublish : ISingleFilePublish
|
||||
"ThingsGateway.Gateway.Application",
|
||||
"ThingsGateway.Gateway.Razor" ,
|
||||
"ThingsGateway.Gateway.ASPNetCore" ,
|
||||
"ThingsGateway.Gateway.NetCore" ,
|
||||
"ThingsGateway.Admin.Razor" ,
|
||||
"ThingsGateway.Admin.Application" ,
|
||||
"ThingsGateway.Admin.ASPNetCore" ,
|
||||
"ThingsGateway.Admin.NetCore" ,
|
||||
"SqlSugar.TDengineCore",
|
||||
];
|
||||
}
|
||||
|
@@ -8,12 +8,19 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using CSScriptLib;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Admin.Razor;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.Logging;
|
||||
|
||||
using UAParser;
|
||||
|
||||
namespace ThingsGateway.Server;
|
||||
|
||||
@@ -22,6 +29,8 @@ public class Startup : AppStartup
|
||||
{
|
||||
public void ConfigBlazorServer(IServiceCollection services)
|
||||
{
|
||||
CSScript.EvaluatorConfig.ReferenceDomainAssemblies = false;
|
||||
services.AddScoped<IGatewayExportService, GatewayExportService>();
|
||||
// 增加网站服务
|
||||
AddWebSiteServices(services);
|
||||
}
|
||||
@@ -32,6 +41,66 @@ public class Startup : AppStartup
|
||||
/// <param name="services"></param>
|
||||
private IServiceCollection AddWebSiteServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
|
||||
#region api日志
|
||||
|
||||
//Monitor日志配置
|
||||
services.AddMonitorLogging(options =>
|
||||
{
|
||||
options.JsonIndented = true;// 是否美化 JSON
|
||||
options.GlobalEnabled = false;//全局启用
|
||||
options.ConfigureLogger((logger, logContext, context) =>
|
||||
{
|
||||
var httpContext = context.HttpContext;//获取httpContext
|
||||
//获取头
|
||||
var userAgent = httpContext.Request.Headers["User-Agent"];
|
||||
if (string.IsNullOrEmpty(userAgent)) userAgent = "Other";//如果没有这个头就指定一个
|
||||
|
||||
var parser = Parser.GetDefault();
|
||||
//获取客户端信息
|
||||
var client = parser.Parse(userAgent);
|
||||
// 获取控制器/操作描述器
|
||||
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
|
||||
//操作名称默认是控制器名加方法名,自定义操作名称要在action上加Description特性
|
||||
var option = $"{controllerActionDescriptor.ControllerName}/{controllerActionDescriptor.ActionName}";
|
||||
|
||||
var desc = NetCoreApp.CreateLocalizerByType(controllerActionDescriptor.ControllerTypeInfo.AsType())[controllerActionDescriptor.MethodInfo.Name];
|
||||
//获取特性
|
||||
option = desc.Value;//则将操作名称赋值为控制器上写的title
|
||||
|
||||
logContext.Set(LoggingConst.CateGory, option);//传操作名称
|
||||
logContext.Set(LoggingConst.Operation, option);//传操作名称
|
||||
logContext.Set(LoggingConst.Client, client);//客户端信息
|
||||
logContext.Set(LoggingConst.Path, httpContext.Request.Path.Value);//请求地址
|
||||
logContext.Set(LoggingConst.Method, httpContext.Request.Method);//请求方法
|
||||
});
|
||||
});
|
||||
//日志写入数据库配置
|
||||
services.AddDatabaseLogging<DatabaseLoggingWriter>(options =>
|
||||
{
|
||||
options.WriteFilter = (logMsg) =>
|
||||
{
|
||||
return logMsg.LogName == "System.Logging.LoggingMonitor";//只写入LoggingMonitor日志
|
||||
};
|
||||
});
|
||||
|
||||
#endregion api日志
|
||||
|
||||
|
||||
services.AddSingleton<IUnifyResultProvider, UnifyResultProvider>();
|
||||
services.AddSingleton<IAuthService, AuthService>();
|
||||
services.AddScoped<IAuthRazorService, AuthRazorService>();
|
||||
services.AddSingleton<IAppService, AspNetCoreAppService>();
|
||||
services.AddSingleton<IApiPermissionService, ApiPermissionService>();
|
||||
|
||||
services.AddSingleton<IFileService, FileService>();
|
||||
services.AddSingleton<IImportExportService, ImportExportService>();
|
||||
|
||||
services.AddSingleton<ISignalrNoticeService, SignalrNoticeService>();
|
||||
services.AddSingleton<IAuthService, AuthService>();
|
||||
|
||||
|
||||
//已添加AddOptions
|
||||
// 增加多语言支持配置信息
|
||||
services.AddRequestLocalization<IOptionsMonitor<BootstrapBlazor.Components.BootstrapBlazorOptions>>((localizerOption, blazorOption) =>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>6.0.5.2</Version>
|
||||
<Version>6.0.5.3</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Mapster;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -40,7 +38,7 @@ public static class DbContext
|
||||
// 配置映射
|
||||
DbConfigs = NetCoreApp.Configuration?.GetSection(nameof(SqlSugarOptions)).Get<SqlSugarOptions>()!;
|
||||
SugarAopService = NetCoreApp.RootServices.GetService<ISugarAopService>();
|
||||
Db = new(DbConfigs.Adapt<List<ConnectionConfig>>(), db =>
|
||||
Db = new(DbConfigs.Select(a => (ConnectionConfig)a).ToList(), db =>
|
||||
{
|
||||
DbConfigs.ForEach(it =>
|
||||
{
|
||||
|
Reference in New Issue
Block a user