!37 release:6.0.5.3

refactor: 完善桌面端版本多语言资源

refactor: 忽略部分文件夹
This commit is contained in:
Diego2098
2024-08-13 08:49:17 +00:00
parent 6bb712854d
commit 0a4416e633
16 changed files with 153 additions and 136 deletions

1
.gitignore vendored
View File

@@ -373,3 +373,4 @@ FodyWeavers.xsd
/src/nupkgs/
/src/nupkgs
/src/.idea/

View File

@@ -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>();
}
}

View File

@@ -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"

View File

@@ -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": "该账号未分配模块,请联系管理员"
}
}

View File

@@ -137,7 +137,6 @@
"CanotDeleteSelf": "不可删除自己",
"EmailError": "邮箱 {0} 格式错误",
"PhoneError": "手机号码 {0} 格式错误",
"UserNoModule": "该账号未分配模块,请联系管理员",
"DemoCanotUpdatePassword": "DEMO环境不允许修改密码",
"OldPasswordError": "原密码错误",

View 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}"
}
}

View 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": "该账号未分配模块,请联系管理员"
}
}

View File

@@ -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>

View File

@@ -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>();
}
}

View File

@@ -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>();

View File

@@ -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)

View File

@@ -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",
];

View File

@@ -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",
];
}

View File

@@ -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) =>

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>6.0.5.2</Version>
<Version>6.0.5.3</Version>
</PropertyGroup>
<ItemGroup>

View File

@@ -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 =>
{