Compare commits

..

28 Commits

Author SHA1 Message Date
Kimdiego2098
2c197ed2b2 2.1.0.7 2023-09-05 09:06:39 +08:00
Kimdiego2098
d8fc6665b3 fix:error!the stream dispose 2023-09-05 09:04:34 +08:00
Kimdiego2098
c671a79822 Revert "fix:error!the stearm dispose"
This reverts commit a6d99fe227.
2023-09-05 09:03:49 +08:00
Kimdiego2098
9d93ce4c41 feat:mqttBroker part 2023-09-05 08:58:49 +08:00
Kimdiego2098
a6d99fe227 fix:error!the stearm dispose 2023-09-05 08:57:42 +08:00
Diego2098
923b8bca31 feat:mqttBroker part 2023-09-04 22:34:31 +08:00
Diego2098
e2c30d1c88 fix:uploadDeivce复制多个,ID重复问题 2023-09-04 22:11:50 +08:00
Diego2098
b6d9f2a04e 刷新后选择行清空 2023-09-04 22:09:26 +08:00
Diego2098
57306ea664 fix:采集设备线程初始化时更新活跃时间 2023-09-04 20:13:49 +08:00
Diego2098
cd7f3fd02f fix:特殊情况下无法获取程序集文件修改日期,所以去除 页脚-编译时间显示 2023-09-04 19:49:17 +08:00
Kimdiego2098
0482e077a8 fix:sqlsugar json支持类型改为bigstring 2023-09-04 17:09:38 +08:00
Kimdiego2098
5f986a45ca 更新文档 2023-09-04 15:03:03 +08:00
Kimdiego2098
ca7b49c0d5 恢复Sqlite默认数据库 2023-09-02 19:17:32 +08:00
Kimdiego2098
52dd555e6c fix: page取消注入瞬时服务,改为App.GetService 2023-09-02 19:13:57 +08:00
Kimdiego2098
579b1a59f9 feat:mqttBroker part 2023-09-02 13:55:21 +08:00
Kimdiego2098
5299c5c4be 更新文档 2023-08-31 09:17:59 +08:00
Kimdiego2098
f7756bccef 更新 变量管理-上传设备筛选功能 2023-08-31 08:58:30 +08:00
Kimdiego2098
a6b874d160 2.1.0.6 2023-08-30 17:19:18 +08:00
Kimdiego2098
3e5fb3ddcf add windows service create/delete bat 2023-08-30 17:18:35 +08:00
Kimdiego2098
5e6bcb12d3 update statusPage; 2023-08-30 14:12:50 +08:00
Kimdiego2098
14303f1429 默认检测重连频率为10分钟 2023-08-29 17:56:59 +08:00
Kimdiego2098
96711ba022 2.1.0.5 2023-08-29 17:44:28 +08:00
Kimdiego2098
cbfc0fdbdc 添加报文日志入库选项 2023-08-29 17:42:56 +08:00
Kimdiego2098
6e81886c0e 添加 页脚 编译时间显示 2023-08-29 17:01:46 +08:00
Kimdiego2098
2d976bc132 调整导入excel错误提示 2023-08-29 16:45:54 +08:00
Kimdiego2098
57f6a476af update opcdaclient null error 2023-08-29 15:24:29 +08:00
Kimdiego2098
8491ed296e update GetBoolValue 2023-08-29 12:40:21 +08:00
Kimdiego2098
cd1288afdc 调整种子文件,增加Pro版本种子文件录入 2023-08-29 09:42:54 +08:00
151 changed files with 1356 additions and 708 deletions

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Version>2.1.0.4</Version>
<Version>2.1.0.7</Version>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>

View File

@@ -19,7 +19,7 @@
<MSheet>
<MCard Flat Href=@CONFIG_COPYRIGHT_URL Target="_blank">
<MLabel Style="background-color:inherit;" Class="text-subtltie-2">@CONFIG_COPYRIGHT</MLabel>
<MLabel Style="background-color:inherit;" Class="text-subtltie-2 ml-4">@Version</MLabel>
<MLabel Style="background-color:inherit;white-space: pre;" Class="text-subtltie-2 ml-4">@Version</MLabel>
</MCard>
</MSheet>

View File

@@ -14,6 +14,8 @@ using Microsoft.AspNetCore.Components;
using System.Reflection;
using ThingsGateway.Admin.Core;
namespace ThingsGateway.Admin.Blazor.Core;
/// <summary>
/// Foter
@@ -40,7 +42,12 @@ public partial class Foter
/// <inheritdoc/>
protected override async Task OnParametersSetAsync()
{
Version = "v" + Assembly.GetExecutingAssembly().GetName().Version.ToString();
var assembly = Assembly.GetEntryAssembly();
if (assembly != null)
{
Version = $"v{assembly.GetName().Version}";
}
await base.OnParametersSetAsync();
}

View File

@@ -282,6 +282,7 @@ public partial class AppDataTable<TItem, SearchItem, AddItem, EditItem> : IAppDa
{
SearchModel.Size = PageItems.Total;
}
selectedItem = new List<TItem>();
}
catch (Exception ex)
{

View File

@@ -14,8 +14,7 @@
@using System.Linq.Expressions;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject IConfigService ConfigService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -41,26 +41,26 @@ public partial class Config
MainLayout MainLayout { get; set; }
private Task AddCallAsync(ConfigAddInput input)
{
return ConfigService.AddAsync(input);
return App.GetService<ConfigService>().AddAsync(input);
}
private Task DeleteCallAsync(IEnumerable<SysConfig> sysConfigs)
{
return ConfigService.DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
return App.GetService<ConfigService>().DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
}
private Task EditCallAsync(ConfigEditInput sysConfigs)
{
return ConfigService.EditAsync(sysConfigs);
return App.GetService<ConfigService>().EditAsync(sysConfigs);
}
private async Task OnSaveAsync()
{
await ConfigService.EditBatchAsync(_sysConfig);
await App.GetService<ConfigService>().EditBatchAsync(_sysConfig);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
private Task<SqlSugarPagedList<SysConfig>> QueryCallAsync(ConfigPageInput input)
{
return ConfigService.PageAsync(input);
return App.GetService<ConfigService>().PageAsync(input);
}
}

View File

@@ -16,7 +16,7 @@
@using Masa.Blazor.Presets;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject IMenuService MenuService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inherits BaseComponentBase

View File

@@ -29,14 +29,11 @@ public partial class Menu
long buttonParentId;
bool IsShowButtonList;
List<SysResource> MenuCatalog = new();
[Inject]
IButtonService ButtonService { get; set; }
[CascadingParameter]
MainLayout MainLayout { get; set; }
[Inject]
IResourceService ResourceService { get; set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -52,23 +49,23 @@ public partial class Menu
private async Task AddCallAsync(MenuAddInput input)
{
input.ParentId = search.ParentId;
await MenuService.AddAsync(input);
await App.GetService<MenuService>().AddAsync(input);
await NavChangeAsync();
}
private async Task ButtonAddCallAsync(ButtonAddInput input)
{
input.ParentId = buttonParentId;
await ButtonService.AddAsync(input);
await App.GetService<ButtonService>().AddAsync(input);
}
private Task ButtonDeleteCallAsync(IEnumerable<SysResource> input)
{
return ButtonService.DeleteAsync(input.Select(a => a.Id).ToArray());
return App.GetService<ButtonService>().DeleteAsync(input.Select(a => a.Id).ToArray());
}
private Task ButtonEditCallAsync(ButtonEditInput input)
{
return ButtonService.EditAsync(input);
return App.GetService<ButtonService>().EditAsync(input);
}
@@ -92,7 +89,7 @@ public partial class Menu
private async Task<SqlSugarPagedList<SysResource>> ButtonQueryCallAsync(ButtonPageInput input)
{
input.ParentId = buttonParentId;
var data = await ButtonService.PageAsync(input);
var data = await App.GetService<ButtonService>().PageAsync(input);
return data;
}
@@ -103,13 +100,13 @@ public partial class Menu
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
{
await MenuService.DeleteAsync(input.Select(a => a.Id).ToArray());
await App.GetService<MenuService>().DeleteAsync(input.Select(a => a.Id).ToArray());
await NavChangeAsync();
}
private async Task EditCallAsync(MenuEditInput input)
{
await MenuService.EditAsync(input);
await App.GetService<MenuService>().EditAsync(input);
await NavChangeAsync();
}
@@ -117,9 +114,9 @@ public partial class Menu
private async Task<List<SysResource>> GetMenuCatalogAsync()
{
//获取所有菜单
List<SysResource> sysResources = await ResourceService.GetListByCategoryAsync(ResourceCategoryEnum.MENU);
List<SysResource> sysResources = await App.GetService<ResourceService>().GetListByCategoryAsync(ResourceCategoryEnum.MENU);
sysResources = sysResources.Where(it => it.TargetType == TargetTypeEnum.None).ToList();
MenuCatalog = ResourceService.ResourceListToTree(sysResources);
MenuCatalog = App.GetService<ResourceService>().ResourceListToTree(sysResources);
return MenuCatalog;
}
@@ -130,7 +127,7 @@ public partial class Menu
}
private async Task<SqlSugarPagedList<SysResource>> QueryCallAsync(MenuPageInput input)
{
var data = await MenuService.TreeAsync(input);
var data = await App.GetService<MenuService>().TreeAsync(input);
return data.ToPagedList(input);
}

View File

@@ -15,7 +15,7 @@
@using Masa.Blazor.Presets;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject IOpenApiSessionService SessionService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -33,13 +33,13 @@ public partial class OpenApiSession
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
if (confirm)
{
await SessionService.ExitSessionAsync(id);
await App.GetService<OpenApiSessionService>().ExitSessionAsync(id);
}
}
private Task<SqlSugarPagedList<OpenApiSessionOutput>> SessionQueryCallAsync(OpenApiSessionPageInput input)
{
return SessionService.PageAsync(input);
return App.GetService<OpenApiSessionService>().PageAsync(input);
}
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
@@ -57,7 +57,7 @@ public partial class OpenApiSession
VerificatIds = verificats.Select(it => it.Id).ToList(),
Id = verificats.First().UserId
};
await SessionService.ExitVerificatAsync(send);
await App.GetService<OpenApiSessionService>().ExitVerificatAsync(send);
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
}

View File

@@ -15,7 +15,7 @@
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@using Masa.Blazor.Presets;
@inject IOpenApiUserService OpenApiUserService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -31,21 +31,20 @@ public partial class OpenApiUserR
bool IsShowRoles;
List<OpenApiPermissionTreeSelector> RolesChoice = new();
string SearchName;
[Inject]
IRoleService SysRoleService { get; set; }
private Task AddCallAsync(OpenApiUserAddInput input)
{
return OpenApiUserService.AddAsync(input);
return App.GetService<OpenApiUserService>().AddAsync(input);
}
private async Task DeleteCallAsync(IEnumerable<OpenApiUser> users)
{
await OpenApiUserService.DeleteAsync(users.Select(a => a.Id).ToArray());
await App.GetService<OpenApiUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
}
private Task EditCallAsync(OpenApiUserEditInput users)
{
return OpenApiUserService.EditAsync(users);
return App.GetService<OpenApiUserService>().EditAsync(users);
}
private List<OpenApiPermissionTreeSelector> GetRouters()
@@ -61,7 +60,7 @@ public partial class OpenApiUserR
OpenApiUserGrantPermissionInput userGrantRoleInput = new();
userGrantRoleInput.Id = ChoiceUserId;
userGrantRoleInput.PermissionList = RolesChoice.Select(it => it.ApiRoute).ToList();
await OpenApiUserService.GrantRoleAsync(userGrantRoleInput);
await App.GetService<OpenApiUserService>().GrantRoleAsync(userGrantRoleInput);
IsShowRoles = false;
await _datatable?.QueryClickAsync();
}
@@ -73,7 +72,7 @@ public partial class OpenApiUserR
}
private Task<SqlSugarPagedList<OpenApiUser>> QueryCallAsync(OpenApiUserPageInput input)
{
return OpenApiUserService.PageAsync(input);
return App.GetService<OpenApiUserService>().PageAsync(input);
}
private async Task UserStatusChangeAsync(OpenApiUser context, bool enable)
@@ -81,9 +80,9 @@ public partial class OpenApiUserR
try
{
if (enable)
await OpenApiUserService.EnableUserAsync(context.Id);
await App.GetService<OpenApiUserService>().EnableUserAsync(context.Id);
else
await OpenApiUserService.DisableUserAsync(context.Id);
await App.GetService<OpenApiUserService>().DisableUserAsync(context.Id);
}
finally
{

View File

@@ -14,7 +14,7 @@
@using System.Linq.Expressions;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject IOperateLogService OperateLogService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -44,7 +44,7 @@ public partial class Oplog
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
if (confirm)
{
await OperateLogService.DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
await App.GetService<OperateLogService>().DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
await _datatable?.QueryClickAsync();
}
}
@@ -54,7 +54,7 @@ public partial class Oplog
input.Account = search.Account;
input.Category = search.Category;
input.ExeStatus = search.ExeStatus;
return OperateLogService.PageAsync(input);
return App.GetService<OperateLogService>().PageAsync(input);
}
[Inject]
AjaxService AjaxService { get; set; }

View File

@@ -16,7 +16,7 @@
@using Masa.Blazor.Presets;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject IRoleService SysRoleService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -38,27 +38,23 @@ public partial class Role
[CascadingParameter]
MainLayout MainLayout { get; set; }
[Inject]
IResourceService ResourceService { get; set; }
private string SearchKey { get; set; }
[Inject]
ISysUserService SysUserService { get; set; }
private Task AddCallAsync(RoleAddInput input)
{
return SysRoleService.AddAsync(input);
return App.GetService<RoleService>().AddAsync(input);
}
private async Task DeleteCallAsync(IEnumerable<SysRole> sysRoles)
{
await SysRoleService.DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
await App.GetService<RoleService>().DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
await MainLayout.StateHasChangedAsync();
}
private async Task EditCallAsync(RoleEditInput input)
{
await SysRoleService.EditAsync(input);
await App.GetService<RoleService>().EditAsync(input);
await MainLayout.StateHasChangedAsync();
}
private async Task OnRoleHasResuorcesSaveAsync(ModalActionEventArgs args)
@@ -69,7 +65,7 @@ public partial class Role
var data = new List<SysResource>();
userGrantRoleInput.Id = ChoiceRoleId;
userGrantRoleInput.GrantInfoList = RoleHasResuorces;
await SysRoleService.GrantResourceAsync(userGrantRoleInput);
await App.GetService<RoleService>().GrantResourceAsync(userGrantRoleInput);
IsShowResuorces = false;
}
catch (Exception ex)
@@ -86,7 +82,7 @@ public partial class Role
GrantUserInput userGrantRoleInput = new();
userGrantRoleInput.Id = ChoiceRoleId;
userGrantRoleInput.GrantInfoList = UsersChoice.Select(it => it.Id).ToList();
await SysRoleService.GrantUserAsync(userGrantRoleInput);
await App.GetService<RoleService>().GrantUserAsync(userGrantRoleInput);
IsShowUsers = false;
}
catch (Exception ex)
@@ -99,19 +95,19 @@ public partial class Role
private Task<SqlSugarPagedList<SysRole>> QueryCallAsync(RolePageInput input)
{
return SysRoleService.PageAsync(input);
return App.GetService<RoleService>().PageAsync(input);
}
private async Task ResuorceInitAsync()
{
ResTreeSelectors = (await ResourceService.GetRoleGrantResourceMenusAsync());
RoleHasResuorces = (await SysRoleService.OwnResourceAsync(ChoiceRoleId))?.GrantInfoList;
ResTreeSelectors = (await App.GetService<ResourceService>().GetRoleGrantResourceMenusAsync());
RoleHasResuorces = (await App.GetService<RoleService>().OwnResourceAsync(ChoiceRoleId))?.GrantInfoList;
}
private async Task<List<UserSelectorOutput>> UserInitAsync()
{
AllUsers = await SysUserService.UserSelectorAsync(SearchKey);
var data = await SysRoleService.OwnUserAsync(ChoiceRoleId);
AllUsers = await App.GetService<SysUserService>().UserSelectorAsync(SearchKey);
var data = await App.GetService<RoleService>().OwnUserAsync(ChoiceRoleId);
UsersChoice = AllUsers.Where(a => data.Contains(a.Id)).ToList();
return AllUsers;
}

View File

@@ -15,8 +15,7 @@
@using Masa.Blazor.Presets;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject ISessionService SessionService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -33,14 +33,14 @@ public partial class Session
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
if (confirm)
{
await SessionService.ExitSessionAsync(id);
await App.GetService<SessionService>().ExitSessionAsync(id);
}
}
private Task<SqlSugarPagedList<SessionOutput>> SessionQueryCallAsync(SessionPageInput input)
{
return SessionService.PageAsync(input);
return App.GetService<SessionService>().PageAsync(input);
}
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
@@ -58,7 +58,7 @@ public partial class Session
VerificatIds = verificats.Select(it => it.Id).ToList(),
Id = verificats.First().UserId
};
await SessionService.ExitVerificatAsync(send);
await App.GetService<SessionService>().ExitVerificatAsync(send);
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
}

View File

@@ -16,7 +16,7 @@
@using Masa.Blazor.Presets;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject ISpaService SpaService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inherits BaseComponentBase

View File

@@ -27,23 +27,23 @@ public partial class Spa
private async Task AddCallAsync(SpaAddInput input)
{
await SpaService.AddAsync(input);
await App.GetService<SpaService>().AddAsync(input);
await MainLayout.StateHasChangedAsync();
}
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
{
await SpaService.DeleteAsync(input.Select(a => a.Id).ToArray());
await App.GetService<SpaService>().DeleteAsync(input.Select(a => a.Id).ToArray());
await MainLayout.StateHasChangedAsync();
}
private async Task EditCallAsync(SpaEditInput input)
{
await SpaService.EditAsync(input);
await App.GetService<SpaService>().EditAsync(input);
await MainLayout.StateHasChangedAsync();
}
private Task<SqlSugarPagedList<SysResource>> QueryCallAsync(SpaPageInput input)
{
return SpaService.PageAsync(input);
return App.GetService<SpaService>().PageAsync(input);
}
}

View File

@@ -11,7 +11,7 @@
*@
@page "/admin/user"
@inject ISysUserService SysUserService
@namespace ThingsGateway.Admin.Blazor
@using Masa.Blazor.Presets;
@using Microsoft.AspNetCore.Authorization;

View File

@@ -34,21 +34,20 @@ public partial class User
[CascadingParameter]
MainLayout MainLayout { get; set; }
[Inject]
IRoleService SysRoleService { get; set; }
private Task AddCallAsync(UserAddInput input)
{
return SysUserService.AddAsync(input);
return App.GetService<SysUserService>().AddAsync(input);
}
private async Task DeleteCallAsync(IEnumerable<SysUser> users)
{
await SysUserService.DeleteAsync(users.Select(a => a.Id).ToArray());
await App.GetService<SysUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
await MainLayout.StateHasChangedAsync();
}
private async Task EditCallAsync(UserEditInput users)
{
await SysUserService.EditAsync(users);
await App.GetService<SysUserService>().EditAsync(users);
await MainLayout.StateHasChangedAsync();
}
@@ -59,7 +58,7 @@ public partial class User
UserGrantRoleInput userGrantRoleInput = new();
userGrantRoleInput.Id = ChoiceUserId;
userGrantRoleInput.RoleIdList = RolesChoice.Select(it => it.Id).ToList();
await SysUserService.GrantRoleAsync(userGrantRoleInput);
await App.GetService<SysUserService>().GrantRoleAsync(userGrantRoleInput);
IsShowRoles = false;
}
catch (Exception ex)
@@ -71,20 +70,20 @@ public partial class User
}
private Task<SqlSugarPagedList<SysUser>> QueryCallAsync(UserPageInput input)
{
return SysUserService.PageAsync(input);
return App.GetService<SysUserService>().PageAsync(input);
}
private async Task ResetPasswordAsync(SysUser sysUser)
{
await SysUserService.ResetPasswordAsync(sysUser.Id);
await App.GetService<SysUserService>().ResetPasswordAsync(sysUser.Id);
await PopupService.EnqueueSnackbarAsync(new("成功", AlertTypes.Success));
await MainLayout.StateHasChangedAsync();
}
private async Task RoleInitAsync()
{
AllRoles = await SysRoleService.RoleSelectorAsync();
var data = await SysRoleService.GetRoleIdListByUserIdAsync(ChoiceUserId);
AllRoles = await App.GetService<RoleService>().RoleSelectorAsync();
var data = await App.GetService<RoleService>().GetRoleIdListByUserIdAsync(ChoiceUserId);
RolesChoice = AllRoles.Where(a => data.Contains(a.Id)).ToList();
}
private async Task UserStatusChangeAsync(SysUser context, bool enable)
@@ -92,9 +91,9 @@ public partial class User
try
{
if (enable)
await SysUserService.EnableUserAsync(context.Id);
await App.GetService<SysUserService>().EnableUserAsync(context.Id);
else
await SysUserService.DisableUserAsync(context.Id);
await App.GetService<SysUserService>().DisableUserAsync(context.Id);
}
finally
{

View File

@@ -33,8 +33,7 @@ public partial class UserCenter
[Inject]
NavigationManager NavigationManager { get; set; }
[Inject]
IUserCenterService UserCenterService { get; set; }
/// <inheritdoc/>
protected override async Task OnParametersSetAsync()
@@ -48,14 +47,14 @@ public partial class UserCenter
async Task OnDefaultRazorSaveAsync()
{
await UserCenterService.UpdateUserDefaultRazorAsync(UserManager.UserId, DefaultMenuId);
await App.GetService<UserCenterService>().UpdateUserDefaultRazorAsync(UserManager.UserId, DefaultMenuId);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
async Task OnShortcutSaveAsync()
{
await UserCenterService.UpdateWorkbenchAsync(_menusChoice);
await App.GetService<UserCenterService>().UpdateWorkbenchAsync(_menusChoice);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
@@ -66,7 +65,7 @@ public partial class UserCenter
{
//验证成功,操作业务
_passwordInfoInput.Id = UserResoures.CurrentUser.Id;
await UserCenterService.EditPasswordAsync(_passwordInfoInput);
await App.GetService<UserCenterService>().EditPasswordAsync(_passwordInfoInput);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("成功,将重新登录", AlertTypes.Success);
await Task.Delay(2000);
@@ -76,7 +75,7 @@ public partial class UserCenter
async Task OnUpdateUserInfoAsync()
{
await UserCenterService.UpdateUserInfoAsync(_updateInfoInput);
await App.GetService<UserCenterService>().UpdateUserInfoAsync(_updateInfoInput);
await MainLayout.StateHasChangedAsync();
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}

View File

@@ -14,8 +14,7 @@
@using System.Linq.Expressions;
@using Microsoft.AspNetCore.Authorization;
@using ThingsGateway.Admin.Application;
@inject IVisitLogService VisitLogService
@namespace ThingsGateway.Admin.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -51,14 +51,14 @@ public partial class Vislog
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
if (confirm)
{
await VisitLogService.DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
await App.GetService<VisitLogService>().DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
await _datatable?.QueryClickAsync();
}
}
private async Task<SqlSugarPagedList<SysVisitLog>> QueryCallAsync(VisitLogPageInput input)
{
var data = await VisitLogService.PageAsync(input);
var data = await App.GetService<VisitLogService>().PageAsync(input);
return data;
}
[Inject]

View File

@@ -40,10 +40,6 @@ public partial class Login
AjaxService AjaxService { get; set; }
[Inject]
IAuthService AuthService { get; set; }
string UserLogoUrl { get; set; } = BlazorResourceConst.ResourceUrl + "images/defaultUser.svg";
@@ -65,12 +61,7 @@ public partial class Login
}
}
private PImageCaptcha captcha;
[Inject]
IUserCenterService UserCenterService { get; set; }
[Inject]
IResourceService ResourceService { get; set; }
[Inject]
ISysUserService SysUserService { get; set; }
private async Task LoginAsync()
{
loginModel.ValidCodeReqNo = CaptchaInfo.ValidCodeReqNo;
@@ -102,9 +93,9 @@ public partial class Login
{
await PopupService.EnqueueSnackbarAsync(new("登录成功", AlertTypes.Success));
await Task.Delay(500);
var userId = await SysUserService.GetIdByAccountAsync(loginModel.Account);
var data = await UserCenterService.GetLoginDefaultRazorAsync(userId);
var sameLevelMenus = await ResourceService.GetaMenuAndSpaListAsync();
var userId = await App.GetService<SysUserService>().GetIdByAccountAsync(loginModel.Account);
var data = await App.GetService<UserCenterService>().GetLoginDefaultRazorAsync(userId);
var sameLevelMenus = await App.GetService<ResourceService>().GetaMenuAndSpaListAsync();
if (NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/Login" || NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/")
await AjaxService.GotoAsync(sameLevelMenus.FirstOrDefault(a => a.Id == data)?.Component ?? "index");
else
@@ -141,12 +132,12 @@ public partial class Login
private void GetCaptchaInfo()
{
CaptchaInfo = AuthService.GetCaptchaInfo();
CaptchaInfo = App.GetService<AuthService>().GetCaptchaInfo();
}
private Task<string> RefreshCode()
{
CaptchaInfo = AuthService.GetCaptchaInfo();
CaptchaInfo = App.GetService<AuthService>().GetCaptchaInfo();
return Task.FromResult(CaptchaInfo.CodeValue);
}
}

View File

@@ -86,7 +86,7 @@ public class OpenApiUser : BaseEntity
/// <summary>
/// 权限码集合
/// </summary>
[SugarColumn(ColumnName = "PermissionCodeList", ColumnDescription = "权限json", IsJson = true, IsNullable = true)]
[SugarColumn(ColumnName = "PermissionCodeList", ColumnDescription = "权限json", ColumnDataType = StaticConfig.CodeFirst_BigString, IsJson = true, IsNullable = true)]
public List<string> PermissionCodeList { get; set; }
/// <summary>

View File

@@ -31,7 +31,7 @@ public class SysVerificat : PrimaryIdEntity
/// <summary>
/// 会话信息列表
/// </summary>
[SugarColumn(IsJson = true)]
[SugarColumn(ColumnName = "VerificatInfos", ColumnDescription = "会话信息列表", ColumnDataType = StaticConfig.CodeFirst_BigString, IsJson = true, IsNullable = true)]
public List<VerificatInfo> VerificatInfos { get; set; }
}

View File

@@ -332,20 +332,51 @@ public static class ObjectExtensions
/// <returns></returns>
public static bool ToBoolean(this object value, bool defaultValue = false) => value?.ToString().ToUpper() switch
{
"0" or "FALSE" => false,
"1" or "TRUE" => true,
_ => defaultValue,
};
/// <summary>
/// ToLong
/// </summary>
/// <returns></returns>
public static long ToLong(this object value, long defaultValue = 0) => value == null || value.ToString().IsNullOrEmpty() ? defaultValue : Int64.TryParse(value.ToString(), out var n) ? n : defaultValue;
public static long ToLong(this object value, long defaultValue = 0)
{
if (value == null || value.ToString().IsNullOrEmpty())
{
return defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return Int64.TryParse(value.ToString(), out var n) ? n : defaultValue;
}
}
/// <summary>
/// ToInt
/// </summary>
/// <returns></returns>
public static int ToInt(this object value, int defaultValue = 0) => value == null || value.ToString().IsNullOrEmpty() ? defaultValue : Int32.TryParse(value.ToString(), out var n) ? n : defaultValue;
public static int ToInt(this object value, int defaultValue = 0)
{
if (value == null || value.ToString().IsNullOrEmpty())
{
return defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return int.TryParse(value.ToString(), out int n) ? n : defaultValue;
}
}
/// <summary>
/// ToDecimal
/// </summary>
@@ -357,7 +388,18 @@ public static class ObjectExtensions
return Double.IsNaN(d) ? defaultValue : (Decimal)d;
}
var str = value?.ToString();
return str.IsNullOrEmpty() ? defaultValue : Decimal.TryParse(str, out var n) ? n : defaultValue;
if (str.IsNullOrEmpty())
{
return defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return Decimal.TryParse(str, out var n) ? n : defaultValue;
}
}
/// <summary>
/// ToDecimal
@@ -370,7 +412,18 @@ public static class ObjectExtensions
return Double.IsNaN(d) ? defaultValue : (Double)d;
}
var str = value?.ToString();
return str.IsNullOrEmpty() ? defaultValue : double.TryParse(str, out var n) ? n : defaultValue;
if (str.IsNullOrEmpty())
{
return (double)defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return (double)(double.TryParse(str, out var n) ? n : defaultValue);
}
}
/// <summary>

View File

@@ -12,6 +12,8 @@
using SqlSugar;
using System.Linq.Expressions;
namespace ThingsGateway.Admin.Core;
/// <summary>
@@ -55,12 +57,14 @@ public static class SqlSugarPageExtension
/// <param name="whereExpression"></param>
/// <returns></returns>
public static async Task<SqlSugarPagedList<TEntity>> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> queryable,
int pageIndex, int pageSize, Func<TEntity, bool> whereExpression = null)
int pageIndex, int pageSize, Expression<Func<TEntity, bool>> whereExpression = null)
{
RefAsync<int> totalCount = 0;
if (whereExpression != null)
queryable = queryable.Where(whereExpression);
var records = await queryable.ToPageListAsync(pageIndex, pageSize, totalCount);
records = whereExpression != null ? records.Where(whereExpression).ToList() : records;
//records = whereExpression != null ? records.Where(whereExpression).ToList() : records;
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
return new SqlSugarPagedList<TEntity>
{

View File

@@ -9,10 +9,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.41" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.41" />
<PackageReference Include="Furion.Pure" Version="4.8.8.41" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.102" />
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.42" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.42" />
<PackageReference Include="Furion.Pure" Version="4.8.8.42" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.104" />
<PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
<PackageReference Include="MiniExcel" Version="1.31.2" />

View File

@@ -1495,7 +1495,7 @@
<param name="size"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Admin.Core.SqlSugarPageExtension.ToPagedListAsync``1(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32,System.Func{``0,System.Boolean})">
<member name="M:ThingsGateway.Admin.Core.SqlSugarPageExtension.ToPagedListAsync``1(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
<summary>
SqlSugar分页扩展
</summary>

View File

@@ -72,7 +72,7 @@ public class MemoryVariable : BaseEntity
/// <summary>
/// 变量额外属性Json通常使用为上传设备,List属性
/// </summary>
[SugarColumn(IsJson = true, ColumnName = "VariablePropertys", ColumnDescription = "变量属性Json", IsNullable = true)]
[SugarColumn(IsJson = true, ColumnName = "VariablePropertys", ColumnDataType = StaticConfig.CodeFirst_BigString, ColumnDescription = "变量属性Json", IsNullable = true)]
[IgnoreExcel]
public ConcurrentDictionary<long, List<DependencyProperty>> VariablePropertys { get; set; } = new();
/// <summary>

View File

@@ -65,7 +65,7 @@ public class UploadDevice : BaseEntity
/// <summary>
/// 设备属性Json
/// </summary>
[SugarColumn(IsJson = true, ColumnName = "DevicePropertys", ColumnDescription = "设备属性Json", IsNullable = true)]
[SugarColumn(IsJson = true, ColumnName = "DevicePropertys", ColumnDataType = StaticConfig.CodeFirst_BigString, ColumnDescription = "设备属性Json", IsNullable = true)]
[IgnoreExcel]
public List<DependencyProperty> DevicePropertys { get; set; }

View File

@@ -113,8 +113,9 @@ public class HardwareInfoService : ISingleton
try
{
var url = "http://myip.ipip.net";
var stream = await new HttpClient().GetStreamAsync(url);
var streamReader = new StreamReader(stream, Encoding.UTF8);
using var httpClient = new HttpClient();
using var stream = await httpClient.GetStreamAsync(url);
using var streamReader = new StreamReader(stream, Encoding.UTF8);
var html = streamReader.ReadToEnd();
return html.Replace("当前 IP", "").Replace("来自于:", "");
}

View File

@@ -0,0 +1,144 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using ThingsGateway.Foundation;
namespace ThingsGateway.Application;
/// <summary>
/// ManageGatewayConfig
/// </summary>
public class ManageGatewayConfig
{
/// <summary>
/// 启用
/// </summary>
public bool Enable { get; set; }
/// <summary>
/// MqttBrokerIP
/// </summary>
public string MqttBrokerIP { get; set; }
/// <summary>
/// MqttBrokerPort
/// </summary>
public int MqttBrokerPort { get; set; }
/// <summary>
/// UserName
/// </summary>
public string UserName { get; set; }
/// <summary>
/// Password
/// </summary>
public string Password { get; set; }
/// <summary>
/// DBDownTopicRpc返回为{DBDownTopic}/Return
/// </summary>
public string DBDownTopic { get; set; }
/// <summary>
/// DBUploadTopicRpc返回为{DBUploadTopic}/Return
/// </summary>
public string DBUploadTopic { get; set; }
/// <summary>
/// WriteRpcTopicRpc返回为{WriteRpcTopic}/Return
/// </summary>
public string WriteRpcTopic { get; set; }
}
/// <summary>
/// 用于Mqtt Json传输上传/下载配置信息
/// </summary>
public class MqttDB
{
/// <summary>
/// 标识
/// </summary>
public string GatewayId { get; set; }
/// <summary>
/// 采集设备
/// </summary>
public List<CollectDevice> CollectDevices { get; set; }
/// <summary>
/// true=>删除全部后增加
/// </summary>
public bool IsCollectDevicesFullUp { get; set; }
/// <summary>
/// 上传设备
/// </summary>
public List<UploadDevice> UploadDevices { get; set; }
/// <summary>
/// true=>删除全部后增加
/// </summary>
public bool IsUploadDevicesFullUp { get; set; }
/// <summary>
/// 变量
/// </summary>
public List<DeviceVariable> DeviceVariables { get; set; }
/// <summary>
/// true=>删除全部后增加
/// </summary>
public bool IsDeviceVariablesFullUp { get; set; }
/// <summary>
/// 配置项
/// </summary>
public List<SysConfig> SysConfigs { get; set; }
}
/// <summary>
/// MqttRpc传入
/// </summary>
public class ManageMqttRpcFrom
{
/// <summary>
/// 标识
/// </summary>
public string GatewayId { get; set; }
/// <summary>
/// 标识
/// </summary>
public string RpcId { get; set; }
/// <summary>
/// "WriteInfos":{"test":"1"}
/// </summary>
public Dictionary<string, string> WriteInfos { get; set; } = new();
}
/// <summary>
/// MqttRpc输出
/// </summary>
public class ManageMqttRpcResult
{
/// <summary>
/// 标识
/// </summary>
public string GatewayId { get; set; }
/// <summary>
/// 标识
/// </summary>
public string RpcId { get; set; }
/// <summary>
/// 消息
/// </summary>
public Dictionary<string, OperResult> Message { get; set; } = new();
/// <summary>
/// 是否成功
/// </summary>
public bool Success { get; set; }
}

View File

@@ -0,0 +1,289 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Furion;
using Furion.Logging.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Server;
using System.Net;
using ThingsGateway.Foundation;
using TouchSocket.Core;
namespace ThingsGateway.Application;
/// <summary>
/// 设备采集报警后台服务
/// </summary>
public class ManageGatewayWorker : BackgroundService
{
private readonly ILogger _logger;
private readonly ILogger _manageLogger;
private readonly ILogger _clientLogger;
/// <inheritdoc cref="ManageGatewayWorker"/>
public ManageGatewayWorker(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger("ManageGatewayWorker");
_manageLogger = loggerFactory.CreateLogger("管理网关(mqttBroker)");
_clientLogger = loggerFactory.CreateLogger("子网关(mqttClient)");
}
/// <summary>
/// 服务状态
/// </summary>
public OperResult RealAlarmStatuString { get; set; } = new OperResult("初始化");
/// <summary>
/// 服务状态
/// </summary>
public OperResult HisAlarmStatuString { get; set; } = new OperResult("初始化");
/// <summary>
/// 服务状态
/// </summary>
public OperResult ReadAlarmStatuString { get; set; } = new OperResult("初始化");
private MqttServer _mqttServer;
private IMqttClient _mqttClient;
#region worker服务
/// <inheritdoc/>
public override async Task StartAsync(CancellationToken token)
{
_logger?.LogInformation("ManageGatewayWorker启动");
await RestartAsync();
await base.StartAsync(token);
}
/// <inheritdoc/>
public override Task StopAsync(CancellationToken token)
{
_logger?.LogInformation("ManageGatewayWorker停止");
return base.StopAsync(token);
}
/// <inheritdoc/>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Delay(5000, stoppingToken);
while (!stoppingToken.IsCancellationRequested)
{
try
{
await Task.Delay(60000, stoppingToken);
}
catch (TaskCanceledException)
{
}
catch (ObjectDisposedException)
{
}
}
}
#endregion
#region
/// <summary>
/// 全部重启锁
/// </summary>
private readonly EasyLock restartLock = new();
/// <summary>
/// 重启
/// </summary>
/// <returns></returns>
public async Task RestartAsync()
{
await StopAsync();
await StartAsync();
}
internal async Task StartAsync()
{
try
{
//重启操作在未完全之前直接取消
if (restartLock.IsWaitting)
{
return;
}
await restartLock.WaitAsync();
await InitAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "启动错误");
}
finally
{
restartLock.Release();
}
}
internal async Task StopAsync()
{
try
{
//重启操作在未完全之前直接取消
if (restartLock.IsWaitting)
{
return;
}
await restartLock.WaitAsync();
_mqttClient?.SafeDispose();
_mqttServer?.SafeDispose();
_mqttClient = null;
_mqttServer = null;
}
catch (Exception ex)
{
_logger.LogError(ex, "停止错误");
}
finally
{
restartLock.Release();
}
}
/// <summary>
/// 初始化
/// </summary>
private async Task InitAsync()
{
try
{
var manageGatewayConfig = App.GetConfig<ManageGatewayConfig>("ManageGatewayConfig");
if (manageGatewayConfig?.Enable != true)
{
HisAlarmStatuString = new OperResult($"已退出:不启用管理功能");
return;
}
else
{
var mqttFactory = new MqttFactory(new MqttNetLogger(_manageLogger));
var mqttServerOptions = mqttFactory.CreateServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(string.IsNullOrEmpty(manageGatewayConfig.MqttBrokerIP) ? null : IPAddress.Parse(manageGatewayConfig.MqttBrokerIP))
.WithDefaultEndpointPort(manageGatewayConfig.MqttBrokerPort)
.WithDefaultEndpoint()
.Build();
_mqttServer = mqttFactory.CreateMqttServer(mqttServerOptions);
if (_mqttServer != null)
{
_mqttServer.ValidatingConnectionAsync += MqttServer_ValidatingConnectionAsync;
_mqttServer.InterceptingPublishAsync += MqttServer_InterceptingPublishAsync;
_mqttServer.LoadingRetainedMessageAsync += MqttServer_LoadingRetainedMessageAsync;
_mqttServer.InterceptingSubscriptionAsync += MqttServer_InterceptingSubscriptionAsync; ;
await _mqttServer.StartAsync();
}
}
}
catch (Exception ex)
{
_manageLogger.LogError(ex, "初始化失败");
}
try
{
var clientGatewayConfig = App.GetConfig<ManageGatewayConfig>("ClientGatewayConfig");
if (clientGatewayConfig?.Enable != true)
{
RealAlarmStatuString = new OperResult($"已退出:不启用子网关功能");
return;
}
else
{
var mqttFactory = new MqttFactory(new MqttNetLogger(_clientLogger));
var _mqttClientOptions = mqttFactory.CreateClientOptionsBuilder()
.WithCredentials(clientGatewayConfig.UserName, clientGatewayConfig.Password)//账密
.WithTcpServer(clientGatewayConfig.MqttBrokerIP, clientGatewayConfig.MqttBrokerPort)//服务器
.WithCleanSession(true)
.WithKeepAlivePeriod(TimeSpan.FromSeconds(120.0))
.WithoutThrowOnNonSuccessfulConnectResponse()
.Build();
var _mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
.WithTopicFilter(
f =>
{
f.WithTopic(clientGatewayConfig.WriteRpcTopic);
f.WithAtMostOnceQoS();
})
.WithTopicFilter(
f =>
{
f.WithTopic(clientGatewayConfig.DBDownTopic);
f.WithAtMostOnceQoS();
})
.WithTopicFilter(
f =>
{
f.WithTopic(clientGatewayConfig.DBUploadTopic);
f.WithAtMostOnceQoS();
})
.Build();
_mqttClient = mqttFactory.CreateMqttClient();
_mqttClient.ConnectedAsync += MqttClient_ConnectedAsync;
_mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
}
}
catch (Exception ex)
{
_clientLogger.LogError(ex, "初始化失败");
}
}
private Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs args)
{
throw new NotImplementedException();
}
private Task MqttClient_ConnectedAsync(MqttClientConnectedEventArgs args)
{
throw new NotImplementedException();
}
private Task MqttServer_InterceptingSubscriptionAsync(InterceptingSubscriptionEventArgs args)
{
throw new NotImplementedException();
}
private Task MqttServer_LoadingRetainedMessageAsync(LoadingRetainedMessagesEventArgs args)
{
throw new NotImplementedException();
}
private Task MqttServer_InterceptingPublishAsync(InterceptingPublishEventArgs args)
{
throw new NotImplementedException();
}
private Task MqttServer_ValidatingConnectionAsync(ValidatingConnectionEventArgs args)
{
throw new NotImplementedException();
}
#endregion
}

View File

@@ -0,0 +1,50 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Microsoft.Extensions.Logging;
using MQTTnet.Diagnostics;
namespace ThingsGateway.Application;
internal class MqttNetLogger : IMqttNetLogger
{
readonly ILogger LogMessage;
public MqttNetLogger(ILogger logger)
{
LogMessage = logger;
}
public bool IsEnabled => true;
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
{
switch (logLevel)
{
case MqttNetLogLevel.Verbose:
LogMessage?.Log(LogLevel.Trace, source, message != null ? (parameters != null ? message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty : message) : string.Empty, exception);
break;
case MqttNetLogLevel.Info:
LogMessage?.Log(LogLevel.Information, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
break;
case MqttNetLogLevel.Warning:
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
break;
case MqttNetLogLevel.Error:
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
break;
}
}
}

View File

@@ -83,7 +83,7 @@ public class DeviceVariableRunTime : DeviceVariable
/// <param name="value"></param>
/// <param name="dateTime"></param>
/// <param name="isOnline"></param>
public OperResult SetValue(object value, DateTime dateTime = default,bool isOnline=true)
public OperResult SetValue(object value, DateTime dateTime = default, bool isOnline = true)
{
try
{

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
@@ -157,7 +159,7 @@ public abstract class CollectBase : DriverBase
{
deviceVariableSourceRead.DeviceVariables.ForEach(it =>
{
var operResult = it.SetValue(null,isOnline:false);
var operResult = it.SetValue(null, isOnline: false);
if (!operResult.IsSuccess)
{
_logger.LogWarning("变量值更新失败:" + operResult.Message);
@@ -220,6 +222,31 @@ public abstract class CollectBase : DriverBase
}
}
internal override void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
{
if (IsSaveLog)
{
if (arg3.StartsWith(FoundationConst.LogMessageHeader))
{
var customLevel = App.GetConfig<Microsoft.Extensions.Logging.LogLevel?>("Logging:LogLevel:BackendLog") ?? Microsoft.Extensions.Logging.LogLevel.Trace;
if ((byte)arg1 < (byte)customLevel)
{
var logRuntime = new BackendLog
{
LogLevel = (Microsoft.Extensions.Logging.LogLevel)arg1,
LogMessage = arg3,
LogSource = "采集设备:" + CurDevice.Name,
LogTime = SysDateTimeExtensions.CurrentDateTime,
Exception = null,
};
_logQueues.Enqueue(logRuntime);
}
}
}
base.NewMessage(arg1, arg2, arg3, arg4);
}
/// <summary>
/// 返回全部内容字节数组
/// <br></br>

View File

@@ -12,7 +12,10 @@
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using ThingsGateway.Foundation;
using ThingsGateway.Foundation.Extension.ConcurrentQueue;
using TouchSocket.Core;
@@ -40,6 +43,7 @@ public abstract class DriverBase : DisposableObject
LogMessage = new LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(Log_Out) { LogLevel = TouchSocket.Core.LogLevel.Trace });
FoundataionConfig.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
Task.Factory.StartNew(LogInsertAsync);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
@@ -67,6 +71,12 @@ public abstract class DriverBase : DisposableObject
/// </summary>
public bool IsLogOut { get; set; }
/// <summary>
/// 是否存储报文
/// </summary>
public bool IsSaveLog { get; set; }
/// <summary>
/// 报文信息
/// </summary>
@@ -82,11 +92,14 @@ public abstract class DriverBase : DisposableObject
/// </summary>
/// <returns></returns>
public abstract bool IsConnected();
/// <summary>
/// 存储日志队列
/// </summary>
protected ConcurrentQueue<BackendLog> _logQueues = new();
/// <summary>
/// 设备报文
/// </summary>
internal void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
internal virtual void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
{
if (IsLogOut)
{
@@ -102,6 +115,27 @@ public abstract class DriverBase : DisposableObject
}
}
private async Task LogInsertAsync()
{
var db = DbContext.Db.CopyNew();
while (!DisposedValue)
{
if (_logQueues.Count > 0)
{
try
{
var data = _logQueues.ToListWithDequeue();
await db.InsertableWithAttr(data).ExecuteCommandAsync();//入库
}
catch
{
}
}
await Task.Delay(5000);
}
}
/// <summary>
/// 底层日志输出

View File

@@ -14,6 +14,8 @@ using Furion;
using Microsoft.Extensions.Logging;
using ThingsGateway.Foundation;
using TouchSocket.Core;
namespace ThingsGateway.Application;
@@ -153,6 +155,32 @@ public abstract class UpLoadBase : DriverBase
_logger.Log_Out(arg1, arg2, arg3, arg4);
}
}
internal override void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
{
if (IsSaveLog)
{
if (arg3.StartsWith(FoundationConst.LogMessageHeader))
{
var customLevel = App.GetConfig<Microsoft.Extensions.Logging.LogLevel?>("Logging:LogLevel:BackendLog") ?? Microsoft.Extensions.Logging.LogLevel.Trace;
if ((byte)arg1 < (byte)customLevel)
{
var logRuntime = new BackendLog
{
LogLevel = (Microsoft.Extensions.Logging.LogLevel)arg1,
LogMessage = arg3,
LogSource = "上传设备:" + CurDevice.Name,
LogTime = SysDateTimeExtensions.CurrentDateTime,
Exception = null,
};
_logQueues.Enqueue(logRuntime);
}
}
}
base.NewMessage(arg1, arg2, arg3, arg4);
}
}

View File

@@ -22,6 +22,9 @@ public class DriverPluginSeedData : ISqlSugarEntitySeedData<DriverPlugin>
/// <inheritdoc/>
public IEnumerable<DriverPlugin> SeedData()
{
return SeedDataUtil.GetSeedData<DriverPlugin>("driver_plugin.json");
return SeedDataUtil.GetSeedData<DriverPlugin>("driver_plugin.json")
.Concat(SeedDataUtil.GetSeedData<DriverPlugin>("pro_driver_plugin.json"))
.Concat(SeedDataUtil.GetSeedData<DriverPlugin>("custom_driver_plugin.json"))
;
}
}

View File

@@ -22,6 +22,6 @@ public class OpenApiUserSeedData : ISqlSugarEntitySeedData<OpenApiUser>
/// <inheritdoc/>
public IEnumerable<OpenApiUser> SeedData()
{
return SeedDataUtil.GetSeedData<OpenApiUser>("gatewayopenapi_user.json");
return SeedDataUtil.GetSeedData<OpenApiUser>("gateway_openapi_user.json");
}
}

View File

@@ -64,10 +64,10 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
[OperDesc("复制上传设备")]
public async Task CopyDevAsync(IEnumerable<UploadDevice> input)
{
var newId = YitIdHelper.NextId();
var newDevs = input.Adapt<List<UploadDevice>>();
newDevs.ForEach(a =>
{
var newId = YitIdHelper.NextId();
a.Id = newId;
a.Name = "Copy-" + a.Name + "-" + newId.ToString();
});

View File

@@ -129,11 +129,11 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
{
uploadDevid = _uploadDeviceService.GetIdByName(input.UploadDeviceName);
}
if (!string.IsNullOrEmpty(input.UploadDeviceName))
{
var pageInfo = await query.ToPagedListAsync(input.Current, input.Size, a => a.VariablePropertys.ContainsKey(uploadDevid ?? 0));//分页
var pageInfo = await query.ToPagedListAsync(input.Current, input.Size, a => SqlFunc.JsonLike(a.VariablePropertys, uploadDevid.ToString()));//分页
return pageInfo;
}
else
{

View File

@@ -44,6 +44,7 @@ public class Startup : AppStartup
services.AddHostedService<AlarmWorker>();
services.AddHostedService<HistoryValueWorker>();
services.AddHostedService<UploadDeviceWorker>();
services.AddHostedService<ManageGatewayWorker>();
}
}

View File

@@ -6,7 +6,7 @@
<ItemGroup>
<None Remove="SeedData\Json\driver_plugin.json" />
<None Remove="SeedData\Json\gatewayopenapi_user.json" />
<None Remove="SeedData\Json\gateway_openapi_user.json" />
<None Remove="SeedData\Json\gateway_relation.json" />
</ItemGroup>
@@ -24,7 +24,7 @@
<Content Include="SeedData\Json\gateway_resource.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="SeedData\Json\gatewayopenapi_user.json">
<Content Include="SeedData\Json\gateway_openapi_user.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="SeedData\Json\gateway_relation.json">
@@ -38,6 +38,7 @@
<PackageReference Include="CS-Script" Version="4.8.1" />
<!--CS-Script与Furion冲突直接安装覆盖版本-->
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.7.0" />
<PackageReference Include="MQTTnet" Version="4.2.1.781" />
</ItemGroup>
<ItemGroup>

View File

@@ -1397,6 +1397,189 @@
<member name="M:ThingsGateway.Application.BackendLogDatabaseLoggingWriter.Write(Furion.Logging.LogMessage,System.Boolean)">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Application.ManageGatewayConfig">
<summary>
ManageGatewayConfig
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.Enable">
<summary>
启用
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.MqttBrokerIP">
<summary>
MqttBrokerIP
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.MqttBrokerPort">
<summary>
MqttBrokerPort
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.UserName">
<summary>
UserName
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.Password">
<summary>
Password
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.DBDownTopic">
<summary>
DBDownTopicRpc返回为{DBDownTopic}/Return
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.DBUploadTopic">
<summary>
DBUploadTopicRpc返回为{DBUploadTopic}/Return
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayConfig.WriteRpcTopic">
<summary>
WriteRpcTopicRpc返回为{WriteRpcTopic}/Return
</summary>
</member>
<member name="T:ThingsGateway.Application.MqttDB">
<summary>
用于Mqtt Json传输上传/下载配置信息
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.GatewayId">
<summary>
标识
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.CollectDevices">
<summary>
采集设备
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.IsCollectDevicesFullUp">
<summary>
true=>删除全部后增加
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.UploadDevices">
<summary>
上传设备
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.IsUploadDevicesFullUp">
<summary>
true=>删除全部后增加
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.DeviceVariables">
<summary>
变量
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.IsDeviceVariablesFullUp">
<summary>
true=>删除全部后增加
</summary>
</member>
<member name="P:ThingsGateway.Application.MqttDB.SysConfigs">
<summary>
配置项
</summary>
</member>
<member name="T:ThingsGateway.Application.ManageMqttRpcFrom">
<summary>
MqttRpc传入
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageMqttRpcFrom.GatewayId">
<summary>
标识
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageMqttRpcFrom.RpcId">
<summary>
标识
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageMqttRpcFrom.WriteInfos">
<summary>
"WriteInfos":{"test":"1"}
</summary>
</member>
<member name="T:ThingsGateway.Application.ManageMqttRpcResult">
<summary>
MqttRpc输出
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.GatewayId">
<summary>
标识
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.RpcId">
<summary>
标识
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.Message">
<summary>
消息
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.Success">
<summary>
是否成功
</summary>
</member>
<member name="T:ThingsGateway.Application.ManageGatewayWorker">
<summary>
设备采集报警后台服务
</summary>
</member>
<member name="M:ThingsGateway.Application.ManageGatewayWorker.#ctor(Microsoft.Extensions.Logging.ILoggerFactory)">
<inheritdoc cref="T:ThingsGateway.Application.ManageGatewayWorker"/>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayWorker.RealAlarmStatuString">
<summary>
服务状态
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayWorker.HisAlarmStatuString">
<summary>
服务状态
</summary>
</member>
<member name="P:ThingsGateway.Application.ManageGatewayWorker.ReadAlarmStatuString">
<summary>
服务状态
</summary>
</member>
<member name="M:ThingsGateway.Application.ManageGatewayWorker.StartAsync(System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Application.ManageGatewayWorker.StopAsync(System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Application.ManageGatewayWorker.ExecuteAsync(System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Application.ManageGatewayWorker.restartLock">
<summary>
全部重启锁
</summary>
</member>
<member name="M:ThingsGateway.Application.ManageGatewayWorker.RestartAsync">
<summary>
重启
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Application.ManageGatewayWorker.InitAsync">
<summary>
初始化
</summary>
</member>
<member name="T:ThingsGateway.Application.CollectDeviceRunTime">
<summary>
采集设备状态表示
@@ -1978,6 +2161,11 @@
是否输出日志
</summary>
</member>
<member name="P:ThingsGateway.Application.DriverBase.IsSaveLog">
<summary>
是否存储报文
</summary>
</member>
<member name="P:ThingsGateway.Application.DriverBase.Messages">
<summary>
报文信息
@@ -1994,6 +2182,11 @@
</summary>
<returns></returns>
</member>
<member name="F:ThingsGateway.Application.DriverBase._logQueues">
<summary>
存储日志队列
</summary>
</member>
<member name="M:ThingsGateway.Application.DriverBase.NewMessage(TouchSocket.Core.LogLevel,System.Object,System.String,System.Exception)">
<summary>
设备报文

View File

@@ -206,6 +206,8 @@ public class CollectDeviceCore
{
try
{
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime);
if (_device == null)
{
_logger?.LogError(nameof(CollectDeviceRunTime) + "设备不能为null");
@@ -287,6 +289,8 @@ public class CollectDeviceCore
{
bool isUpDevice = Device != device;
_device = device;
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime);
_logger = ServiceHelper.Services.GetService<ILoggerFactory>().CreateLogger("采集设备:" + _device.Name);
//更新插件信息
CreatDriver();
@@ -677,9 +681,9 @@ public class CollectDeviceCore
}
else
{
if (isRead&& !result.IsSuccess)
if (isRead && !result.IsSuccess)
{
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null,isOnline: false);
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null, isOnline: false);
if (!operResult.IsSuccess)
{
_logger?.LogWarning(operResult.Message, ToString());

View File

@@ -95,10 +95,13 @@ public class CollectDeviceWorker : BackgroundService
await RemoveAllDeviceThreadAsync();
//创建全部采集线程
await CreatAllDeviceThreadsAsync();
//开始全部采集线程
await StartAllDeviceThreadsAsync();
//开始其他后台服务
await StartOtherHostService();
//开始全部采集线程
await StartAllDeviceThreadsAsync();
}
catch (Exception ex)
{

View File

@@ -75,30 +75,33 @@
(item.Value.HasError ? "出现错误" : "验证成功")
)
</MSubheader>
<MVirtualScroll Context="item1" Height=300 OverscanCount=2 ItemSize="60" Items="item.Value.Results">
<ItemContent>
<MListItem>
<MListItemAction>
<MChip Class="ma-2">
@(
if (item.Value.HasError)
{
<MVirtualScroll Context="item1" Height=300 OverscanCount=2 ItemSize="60" Items="item.Value.Results.Where(a=>!a.isSuccess).ToList()">
<ItemContent>
<MListItem>
<MListItemAction>
<MChip Class="ma-2">
@(
$"第{item1.row}行"
)
</MChip>
</MListItemAction>
</MChip>
</MListItemAction>
<MListItemContent>
<MListItemTitle Class=@((item1.isSuccess?"green--text":"red--text"))>
<strong>@item1.resultString</strong>
</MListItemTitle>
</MListItemContent>
<MListItemContent>
<MListItemTitle Class=@((item1.isSuccess?"green--text":"red--text"))>
<strong>@item1.resultString</strong>
</MListItemTitle>
</MListItemContent>
</MListItem>
</MListItem>
<MDivider></MDivider>
<MDivider></MDivider>
</ItemContent>
</MVirtualScroll>
</ItemContent>
</MVirtualScroll>
}
}

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
using Microsoft.JSInterop;
@@ -65,11 +67,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
/// 写入值
/// </summary>
public virtual string WriteValue { get; set; }
[Inject]
private ICollectDeviceService CollectDeviceService { get; set; }
[Inject]
private IVariableService VariableService { get; set; }
[Inject]
private InitTimezone InitTimezone { get; set; }
@@ -133,7 +131,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
{
isDownExport = true;
StateHasChanged();
await CollectDeviceService.AddAsync(data);
await App.GetService<CollectDeviceService>().AddAsync(data);
}
finally
{
@@ -151,7 +149,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
{
isDownExport = true;
StateHasChanged();
await VariableService.AddBatchAsync(data);
await App.GetService<VariableService>().AddBatchAsync(data);
}
finally
{
@@ -199,7 +197,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await CollectDeviceService.ExportFileAsync(new List<CollectDevice>() { data });
using var memoryStream = await App.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
_helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
@@ -221,7 +219,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await VariableService.ExportFileAsync(data, devName);
using var memoryStream = await App.GetService<VariableService>().ExportFileAsync(data, devName);
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
_helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");

View File

@@ -12,7 +12,7 @@
@page "/gatewaylog/backendlog"
@using System.Linq.Expressions;
@inject IBackendLogService BackendLogService
@inject UserResoures UserResoures
@namespace ThingsGateway.Blazor
@using BlazorComponent;

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Mapster;
using Microsoft.AspNetCore.Components;
@@ -37,7 +39,7 @@ public partial class BackendLogPage
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
if (confirm)
{
await BackendLogService.DeleteAsync();
await App.GetService<BackendLogService>().DeleteAsync();
await _datatable?.QueryClickAsync();
}
}
@@ -56,7 +58,7 @@ public partial class BackendLogPage
private async Task<SqlSugarPagedList<BackendLog>> QueryCallAsync(BackendLogPageInput input)
{
var data = await BackendLogService.PageAsync(input);
var data = await App.GetService<BackendLogService>().PageAsync(input);
return data;
}
}

View File

@@ -14,6 +14,7 @@
@namespace ThingsGateway.Blazor
@using System.Linq.Expressions;
@using BlazorComponent;
@using Furion;
@using Mapster;
@using Masa.Blazor
@using Masa.Blazor.Presets;
@@ -22,11 +23,11 @@
@using ThingsGateway.Admin.Blazor.Core;
@using ThingsGateway.Admin.Blazor;
@using ThingsGateway.Application;
@inject ICollectDeviceService CollectDeviceService
@attribute [Authorize]
@inherits BaseComponentBase
@inject UserResoures UserResoures
@inject IDriverPluginService DriverPluginService
@layout MainLayout
@using ThingsGateway.Admin.Core;
@if (IsMobile)
@@ -172,7 +173,7 @@ else
case nameof(context.Item.PluginId):
<span title=@context.Value>
@(
DriverPluginService.GetNameById(context.Item.PluginId)
App.GetService<DriverPluginService>().GetNameById(context.Item.PluginId)
)
</span>
break;

View File

@@ -57,8 +57,8 @@ public partial class CollectDevicePage
private async Task AddCallAsync(CollectDeviceAddInput input)
{
await CollectDeviceService.AddAsync(input);
CollectDevices = CollectDeviceService.GetCacheList();
await App.GetService<CollectDeviceService>().AddAsync(input);
CollectDevices = App.GetService<CollectDeviceService>().GetCacheList();
_deviceGroups = CollectDevices?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await MainLayout.StateHasChangedAsync();
}
@@ -71,7 +71,7 @@ public partial class CollectDevicePage
return;
}
await CollectDeviceService.CopyDevAndVarAsync(data);
await App.GetService<CollectDeviceService>().CopyDevAndVarAsync(data);
await DatatableQueryAsync();
await PopupService.EnqueueSnackbarAsync("复制成功", AlertTypes.Success);
await MainLayout.StateHasChangedAsync();
@@ -85,7 +85,7 @@ public partial class CollectDevicePage
return;
}
await CollectDeviceService.CopyDevAsync(data);
await App.GetService<CollectDeviceService>().CopyDevAsync(data);
await DatatableQueryAsync();
await PopupService.EnqueueSnackbarAsync("复制成功", AlertTypes.Success);
await MainLayout.StateHasChangedAsync();
@@ -98,15 +98,15 @@ public partial class CollectDevicePage
private async Task DeleteCallAsync(IEnumerable<CollectDevice> input)
{
await CollectDeviceService.DeleteAsync(input.Select(a => a.Id).ToArray());
CollectDevices = CollectDeviceService.GetCacheList();
await App.GetService<CollectDeviceService>().DeleteAsync(input.Select(a => a.Id).ToArray());
CollectDevices = App.GetService<CollectDeviceService>().GetCacheList();
_deviceGroups = CollectDevices?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await MainLayout.StateHasChangedAsync();
}
Task<Dictionary<string, ImportPreviewOutputBase>> DeviceImportAsync(IBrowserFile file)
{
return CollectDeviceService.PreviewAsync(file);
return App.GetService<CollectDeviceService>().PreviewAsync(file);
}
async Task DownExportAsync(CollectDevicePageInput input = null)
{
@@ -133,8 +133,8 @@ public partial class CollectDevicePage
private async Task EditCallAsync(CollectDeviceEditInput input)
{
await CollectDeviceService.EditAsync(input);
CollectDevices = CollectDeviceService.GetCacheList();
await App.GetService<CollectDeviceService>().EditAsync(input);
CollectDevices = App.GetService<CollectDeviceService>().GetCacheList();
_deviceGroups = CollectDevices?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await MainLayout.StateHasChangedAsync();
}
@@ -147,13 +147,13 @@ public partial class CollectDevicePage
private async Task<SqlSugarPagedList<CollectDevice>> QueryCallAsync(CollectDevicePageInput input)
{
var data = await CollectDeviceService.PageAsync(input);
var data = await App.GetService<CollectDeviceService>().PageAsync(input);
return data;
}
async Task SaveDeviceImportAsync(Dictionary<string, ImportPreviewOutputBase> data)
{
await CollectDeviceService.ImportAsync(data);
await App.GetService<CollectDeviceService>().ImportAsync(data);
await DatatableQueryAsync();
ImportExcel.IsShowImport = false;
await MainLayout.StateHasChangedAsync();

View File

@@ -19,8 +19,7 @@
@using ThingsGateway.Admin.Blazor;
@using ThingsGateway.Admin.Core;
@using ThingsGateway.Application;
@inject IConfigService ConfigService
@namespace ThingsGateway.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -56,7 +56,7 @@ public partial class ConfigPage
var confirm = await PopupService.OpenConfirmDialogAsync("确认", "保存配置后将重启报警服务,是否确定?");
if (confirm)
{
await ConfigService.EditBatchAsync(_alarmConfig);
await App.GetService<ConfigService>().EditBatchAsync(_alarmConfig);
await AlarmHostService.RestartAsync();
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}
@@ -67,7 +67,7 @@ public partial class ConfigPage
var confirm = await PopupService.OpenConfirmDialogAsync("确认", "保存配置后将重启历史服务,是否确定?");
if (confirm)
{
await ConfigService.EditBatchAsync(_hisConfig);
await App.GetService<ConfigService>().EditBatchAsync(_hisConfig);
await HistoryValueHostService.RestartAsync();
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
}

View File

@@ -24,14 +24,12 @@
@using ThingsGateway.Admin.Core;
@using ThingsGateway.Application;
@using TouchSocket.Core;
@inject ICollectDeviceService CollectDeviceService
@inject IUploadDeviceService UploadDeviceService
@attribute [Authorize]
@inherits BaseComponentBase
@inject UserResoures UserResoures
@inject NavigationManager NavigationManager
@inject IDriverPluginService DriverPluginService
@layout MainLayout
<MSheet Style="overflow:auto">
@@ -253,6 +251,23 @@
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
OnClick=@(()=>
{
if(collectDeviceInfoItem.Driver!=null)
collectDeviceInfoItem.Driver.IsSaveLog=! collectDeviceInfoItem.Driver.IsSaveLog;
}
)>
<MIcon>@((collectDeviceInfoItem.Driver?.IsSaveLog == true) ? "mdi-pause" : "mdi-play")</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
<span>@((collectDeviceInfoItem.Driver?.IsSaveLog != true) ? "存入数据库,注意若交互频繁,可能导致数据库太大" : "不存入数据库")</span>
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Loading=isDownExport Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
@@ -407,6 +422,10 @@
<span>@(item.Device?.KeepRun == true ? "暂停" : "运行")</span>
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart OnClick=@(()=> UpRestartAsync(item.DeviceId))>
@@ -495,7 +514,22 @@
<span>@((!pauseMessage) ? "暂停日志" : "运行日志")</span>
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
OnClick=@(()=>
{
if(uploadDeviceInfoItem.Driver!=null)
uploadDeviceInfoItem.Driver.IsSaveLog=! uploadDeviceInfoItem.Driver.IsSaveLog;
}
)>
<MIcon>@((uploadDeviceInfoItem.Driver?.IsSaveLog == true) ? "mdi-pause" : "mdi-play")</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
<span>@((uploadDeviceInfoItem.Driver?.IsSaveLog != true) ? "存入数据库,注意若交互频繁,可能导致数据库太大" : "不存入数据库")</span>
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Loading=isDownExport Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small

View File

@@ -73,8 +73,6 @@ public partial class DeviceStatusPage : IDisposable
UploadDeviceWorker UploadDeviceHostService { get; set; }
StringNumber Uppanel { get; set; }
[Inject]
IVariableService VariableService { get; set; }
/// <summary>
/// <inheritdoc/>

View File

@@ -53,8 +53,6 @@ public partial class DeviceVariablePage
[Inject]
AjaxService AjaxService { get; set; }
[Inject]
IVariableService VariableService { get; set; }
/// <summary>
/// <inheritdoc/>
@@ -70,7 +68,7 @@ public partial class DeviceVariablePage
}
private async Task AddCallAsync(DeviceVariableAddInput input)
{
await VariableService.AddAsync(input);
await App.GetService<VariableService>().AddAsync(input);
}
private async Task ClearAsync()
@@ -78,7 +76,7 @@ public partial class DeviceVariablePage
var confirm = await PopupService.OpenConfirmDialogAsync("确认", "清空?");
if (confirm)
{
await VariableService.ClearDeviceVariableAsync();
await App.GetService<VariableService>().ClearDeviceVariableAsync();
}
await DatatableQueryAsync();
@@ -91,7 +89,7 @@ public partial class DeviceVariablePage
private async Task DeleteCallAsync(IEnumerable<DeviceVariable> input)
{
await VariableService.DeleteAsync(input.Select(a => a.Id).ToArray());
await App.GetService<VariableService>().DeleteAsync(input.Select(a => a.Id).ToArray());
}
void DeviceChanged(long devId)
@@ -107,7 +105,7 @@ public partial class DeviceVariablePage
Task<Dictionary<string, ImportPreviewOutputBase>> DeviceImportAsync(IBrowserFile file)
{
return VariableService.PreviewAsync(file);
return App.GetService<VariableService>().PreviewAsync(file);
}
async Task DownExportAsync(DeviceVariablePageInput input = null)
{
@@ -116,7 +114,7 @@ public partial class DeviceVariablePage
private async Task EditCallAsync(VariableEditInput input)
{
await VariableService.EditAsync(input);
await App.GetService<VariableService>().EditAsync(input);
}
List<DependencyProperty> GetDriverProperties(long driverId, List<DependencyProperty> dependencyProperties)
@@ -126,13 +124,13 @@ public partial class DeviceVariablePage
private async Task<SqlSugarPagedList<DeviceVariable>> QueryCallAsync(DeviceVariablePageInput input)
{
var data = await VariableService.PageAsync(input);
var data = await App.GetService<VariableService>().PageAsync(input);
return data;
}
async Task SaveDeviceImportAsync(Dictionary<string, ImportPreviewOutputBase> data)
{
await VariableService.ImportAsync(data);
await App.GetService<VariableService>().ImportAsync(data);
await DatatableQueryAsync();
ImportExcel.IsShowImport = false;
}

View File

@@ -52,8 +52,6 @@ public partial class DeviceVariableRunTimePage
GlobalDeviceData GlobalDeviceData { get; set; }
VariablePageInput SearchModel { get; set; } = new();
[Inject]
IUploadDeviceService UploadDeviceService { get; set; }
CollectDeviceWorker CollectDeviceHostService { get; set; }
[Inject]
@@ -121,7 +119,7 @@ public partial class DeviceVariableRunTimePage
private Task<SqlSugarPagedList<DeviceVariableRunTime>> QueryCallAsync(VariablePageInput input)
{
var uploadDevId = UploadDeviceService.GetIdByName(input.UploadDeviceName);
var uploadDevId = App.GetService<UploadDeviceService>().GetIdByName(input.UploadDeviceName);
var data = GlobalDeviceData.AllVariables
.WhereIF(!input.DeviceName.IsNullOrEmpty(), a => a.DeviceName == input.DeviceName)
.WhereIF(!input.Name.IsNullOrEmpty(), a => a.Name.Contains(input.Name))

View File

@@ -24,11 +24,11 @@
@using ThingsGateway.Admin.Blazor;
@using ThingsGateway.Admin.Core;
@using ThingsGateway.Application;
@inject IVariableService VariableService
@attribute [Authorize]
@inherits BaseComponentBase
@inject UserResoures UserResoures
@inject ICollectDeviceService CollectDeviceService
@layout MainLayout
<MRow NoGutters>

View File

@@ -12,6 +12,8 @@
using BlazorComponent;
using Furion;
using Masa.Blazor;
using Microsoft.AspNetCore.Components;
@@ -33,14 +35,13 @@ public partial class DriverDebugPage
List<DriverPluginCategory> DriverPlugins;
bool IsShowTreeView = true;
PluginDebugUIInput SearchModel { get; set; } = new();
[Inject]
IDriverPluginService DriverPluginService { get; set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
protected override void OnInitialized()
{
DriverPlugins = DriverPluginService.GetDriverPluginChildrenList();
DriverPlugins = App.GetService<DriverPluginService>().GetDriverPluginChildrenList();
base.OnInitialized();
}

View File

@@ -21,7 +21,7 @@
@using ThingsGateway.Admin.Blazor;
@using ThingsGateway.Admin.Core;
@using ThingsGateway.Application;
@inject IDriverPluginService DriverPluginService
@attribute [Authorize]
@inherits BaseComponentBase
@inject UserResoures UserResoures

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using ThingsGateway.Admin.Blazor.Core;
using ThingsGateway.Admin.Core;
using ThingsGateway.Application;
@@ -25,12 +27,12 @@ public partial class DriverPluginPage
private async Task AddCallAsync(DriverPluginAddInput input)
{
await DriverPluginService.AddAsync(input);
await App.GetService<DriverPluginService>().AddAsync(input);
}
private async Task<SqlSugarPagedList<DriverPlugin>> QueryCallAsync(DriverPluginPageInput input)
{
var data = await DriverPluginService.PageAsync(input);
var data = await App.GetService<DriverPluginService>().PageAsync(input);
return data;
}
}

View File

@@ -45,11 +45,6 @@ public partial class MemoryVariablePage
[Inject]
AjaxService AjaxService { get; set; }
[Inject]
InitTimezone InitTimezone { get; set; }
[Inject]
IVariableService VariableService { get; set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -70,7 +65,7 @@ public partial class MemoryVariablePage
private async Task AddCallAsync(MemoryVariableAddInput input)
{
await VariableService.AddAsync(input);
await App.GetService<VariableService>().AddAsync(input);
}
private async Task ClearAsync()
@@ -78,7 +73,7 @@ public partial class MemoryVariablePage
var confirm = await PopupService.OpenConfirmDialogAsync("确认", "清空?");
if (confirm)
{
await VariableService.ClearMemoryVariableAsync();
await App.GetService<VariableService>().ClearMemoryVariableAsync();
}
await DatatableQueryAsync();
@@ -91,12 +86,12 @@ public partial class MemoryVariablePage
private async Task DeleteCallAsync(IEnumerable<DeviceVariable> input)
{
await VariableService.DeleteAsync(input.Select(a => a.Id).ToArray());
await App.GetService<VariableService>().DeleteAsync(input.Select(a => a.Id).ToArray());
}
Task<Dictionary<string, ImportPreviewOutputBase>> DeviceImportAsync(IBrowserFile file)
{
return VariableService.MemoryVariablePreviewAsync(file);
return App.GetService<VariableService>().MemoryVariablePreviewAsync(file);
}
@@ -108,7 +103,7 @@ public partial class MemoryVariablePage
private async Task EditCallAsync(MemoryVariableAddInput input)
{
await VariableService.EditAsync(input);
await App.GetService<VariableService>().EditAsync(input);
}
@@ -119,12 +114,12 @@ public partial class MemoryVariablePage
private async Task<SqlSugarPagedList<DeviceVariable>> QueryCallAsync(MemoryVariablePageInput input)
{
var data = await VariableService.PageAsync(input);
var data = await App.GetService<VariableService>().PageAsync(input);
return data;
}
async Task SaveDeviceImportAsync(Dictionary<string, ImportPreviewOutputBase> data)
{
await VariableService.ImportAsync(data);
await App.GetService<VariableService>().ImportAsync(data);
await DatatableQueryAsync();
ImportExcel.IsShowImport = false;
}

View File

@@ -18,7 +18,7 @@
@using ThingsGateway.Admin.Blazor;
@using ThingsGateway.Admin.Core;
@using ThingsGateway.Application;
@inject IRpcLogService RpcLogService
@namespace ThingsGateway.Blazor
@attribute [Authorize]
@inject UserResoures UserResoures

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Mapster;
using Microsoft.AspNetCore.Components;
@@ -36,7 +38,7 @@ public partial class RpcLogPage
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
if (confirm)
{
await RpcLogService.DeleteAsync();
await App.GetService<RpcLogService>().DeleteAsync();
await _datatable?.QueryClickAsync();
}
}
@@ -54,7 +56,7 @@ public partial class RpcLogPage
private async Task<SqlSugarPagedList<RpcLog>> QueryCallAsync(RpcLogPageInput input)
{
var data = await RpcLogService.PageAsync(input);
var data = await App.GetService<RpcLogService>().PageAsync(input);
return data;
}
}

View File

@@ -14,6 +14,7 @@
@namespace ThingsGateway.Blazor
@using System.Linq.Expressions;
@using BlazorComponent;
@using Furion;
@using Mapster;
@using Masa.Blazor.Presets;
@using System.IO;
@@ -149,7 +150,7 @@ else
case nameof(context.Item.PluginId):
<span title=@context.Value>
@(
DriverPluginService.GetNameById(context.Item.PluginId)
App.GetService<DriverPluginService>().GetNameById(context.Item.PluginId)
)
</span>
break;

View File

@@ -44,16 +44,10 @@ public partial class UploadDevicePage
StringNumber tab;
[Inject]
AjaxService AjaxService { get; set; }
[Inject]
IDriverPluginService DriverPluginService { get; set; }
[Inject]
InitTimezone InitTimezone { get; set; }
[CascadingParameter]
MainLayout MainLayout { get; set; }
[Inject]
IUploadDeviceService UploadDeviceService { get; set; }
/// <summary>
/// <inheritdoc/>
@@ -67,8 +61,8 @@ public partial class UploadDevicePage
}
private async Task AddCallAsync(UploadDeviceAddInput input)
{
await UploadDeviceService.AddAsync(input);
_deviceGroups = UploadDeviceService.GetCacheList()?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await App.GetService<UploadDeviceService>().AddAsync(input);
_deviceGroups = App.GetService<UploadDeviceService>().GetCacheList()?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await MainLayout.StateHasChangedAsync();
}
@@ -80,7 +74,7 @@ public partial class UploadDevicePage
return;
}
await UploadDeviceService.CopyDevAsync(data);
await App.GetService<UploadDeviceService>().CopyDevAsync(data);
await DatatableQuery();
await PopupService.EnqueueSnackbarAsync("复制成功", AlertTypes.Success);
await MainLayout.StateHasChangedAsync();
@@ -93,14 +87,14 @@ public partial class UploadDevicePage
private async Task DeleteCallAsync(IEnumerable<UploadDevice> input)
{
await UploadDeviceService.DeleteAsync(input.Select(a => a.Id).ToArray());
_deviceGroups = UploadDeviceService.GetCacheList()?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await App.GetService<UploadDeviceService>().DeleteAsync(input.Select(a => a.Id).ToArray());
_deviceGroups = App.GetService<UploadDeviceService>().GetCacheList()?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await MainLayout.StateHasChangedAsync();
}
Task<Dictionary<string, ImportPreviewOutputBase>> DeviceImportAsync(IBrowserFile file)
{
return UploadDeviceService.PreviewAsync(file);
return App.GetService<UploadDeviceService>().PreviewAsync(file);
}
async Task DownExportAsync(UploadDevicePageInput input = null)
{
@@ -128,8 +122,8 @@ public partial class UploadDevicePage
}
private async Task EditCallAsync(UploadDeviceEditInput input)
{
await UploadDeviceService.EditAsync(input);
_deviceGroups = UploadDeviceService.GetCacheList()?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await App.GetService<UploadDeviceService>().EditAsync(input);
_deviceGroups = App.GetService<UploadDeviceService>().GetCacheList()?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList();
await MainLayout.StateHasChangedAsync();
}
@@ -141,13 +135,13 @@ public partial class UploadDevicePage
private async Task<SqlSugarPagedList<UploadDevice>> QueryCallAsync(UploadDevicePageInput input)
{
var data = await UploadDeviceService.PageAsync(input);
var data = await App.GetService<UploadDeviceService>().PageAsync(input);
return data;
}
async Task SaveDeviceImportAsync(Dictionary<string, ImportPreviewOutputBase> data)
{
await UploadDeviceService.ImportAsync(data);
await App.GetService<UploadDeviceService>().ImportAsync(data);
await DatatableQuery();
ImportExcel.IsShowImport = false;
await MainLayout.StateHasChangedAsync();

View File

@@ -24,6 +24,8 @@ public static class ReadWriteDevicesExHelpers
/// <returns></returns>
public static bool GetBoolValue(this string value)
{
if (value == null)
return false;
if (value == "1")
return true;
if (value == "0")

View File

@@ -871,8 +871,8 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
#if NET45_OR_GREATER
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
#else
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
@@ -1153,7 +1153,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
if (delaySenderOption != null)
{
this.m_delaySender = new DelaySender(socket, delaySenderOption, this.OnDelaySenderError);
this.m_delaySender = new DelaySender(delaySenderOption, this.MainSocket.AbsoluteSend);
}
}

View File

@@ -1,201 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// 延迟发送器
/// </summary>
public sealed class SerialDelaySender : DisposableObject
{
private readonly ReaderWriterLockSlim m_lockSlim;
private readonly Action<Exception> m_onError;
private readonly IntelligentDataQueue<QueueDataBytes> m_queueDatas;
private readonly SerialPort m_serial;
private volatile bool m_sending;
/// <summary>
/// 延迟发送器
/// </summary>
/// <param name="serialPort"></param>
/// <param name="onError"></param>
/// <param name="delaySenderOption"></param>
public SerialDelaySender(SerialPort serialPort, DelaySenderOption delaySenderOption, Action<Exception> onError)
{
this.DelayLength = delaySenderOption.DelayLength;
this.m_serial = serialPort;
this.m_onError = onError;
this.m_queueDatas = new IntelligentDataQueue<QueueDataBytes>(delaySenderOption.QueueLength);
this.m_lockSlim = new ReaderWriterLockSlim();
}
/// <summary>
/// 延迟包最大尺寸。
/// </summary>
public int DelayLength { get; private set; }
/// <summary>
/// 是否处于发送状态
/// </summary>
public bool Sending
{
get
{
using (new ReadLock(this.m_lockSlim))
{
return this.m_sending;
}
}
private set
{
using (new WriteLock(this.m_lockSlim))
{
this.m_sending = value;
}
}
}
/// <summary>
/// 发送
/// </summary>
public void Send(QueueDataBytes dataBytes)
{
this.m_queueDatas.Enqueue(dataBytes);
if (this.SwitchToRun())
{
Task.Factory.StartNew(this.BeginSend);
}
}
/// <summary>
/// 释放
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
this.m_queueDatas.Clear();
base.Dispose(disposing);
}
private void BeginSend()
{
try
{
var buffer = BytePool.Default.Rent(this.DelayLength);
while (!this.DisposedValue)
{
try
{
if (this.TryGet(buffer, out var asyncByte))
{
this.m_serial.AbsoluteSend(asyncByte.Buffer, asyncByte.Offset, asyncByte.Length);
}
else
{
break;
}
}
catch (Exception ex)
{
this.m_onError?.Invoke(ex);
break;
}
}
BytePool.Default.Return(buffer);
this.Sending = false;
}
catch
{
}
}
private bool SwitchToRun()
{
using (new WriteLock(this.m_lockSlim))
{
if (this.m_sending)
{
return false;
}
else
{
this.m_sending = true;
return true;
}
}
}
private bool TryGet(byte[] buffer, out QueueDataBytes asyncByteDe)
{
var len = 0;
var surLen = buffer.Length;
while (true)
{
if (this.m_queueDatas.TryPeek(out var asyncB))
{
if (surLen > asyncB.Length)
{
if (this.m_queueDatas.TryDequeue(out var asyncByte))
{
Array.Copy(asyncByte.Buffer, asyncByte.Offset, buffer, len, asyncByte.Length);
len += asyncByte.Length;
surLen -= asyncByte.Length;
}
}
else if (asyncB.Length > buffer.Length)
{
if (len > 0)
{
break;
}
else
{
asyncByteDe = asyncB;
return true;
}
}
else
{
break;
}
}
else
{
if (len > 0)
{
break;
}
else
{
asyncByteDe = default;
return false;
}
}
}
asyncByteDe = new QueueDataBytes(buffer, 0, len);
return true;
}
}

View File

@@ -75,7 +75,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
#region
private SerialDelaySender m_delaySender;
private DelaySender m_delaySender;
private long m_bufferRate = 1;
private volatile bool m_online;
ValueCounter m_receiveCounter;
@@ -713,7 +713,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
if (delaySenderOption != null)
{
this.m_delaySender = new SerialDelaySender(MainSerialPort, delaySenderOption, this.OnDelaySenderError);
this.m_delaySender = new DelaySender(delaySenderOption, this.MainSerialPort.AbsoluteSend);
}
}
/// <summary>

View File

@@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="TouchSocket" Version="2.0.0-beta.156" />
<PackageReference Include="TouchSocket" Version="2.0.0-beta.163" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'!='net45'">
<PackageReference Include="System.IO.Ports" Version="7.0.0" />

View File

@@ -1948,40 +1948,6 @@
<member name="P:ThingsGateway.Foundation.Serial.BaseSerial.Logger">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialDelaySender">
<summary>
延迟发送器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialDelaySender.#ctor(System.IO.Ports.SerialPort,TouchSocket.Sockets.DelaySenderOption,System.Action{System.Exception})">
<summary>
延迟发送器
</summary>
<param name="serialPort"></param>
<param name="onError"></param>
<param name="delaySenderOption"></param>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialDelaySender.DelayLength">
<summary>
延迟包最大尺寸。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialDelaySender.Sending">
<summary>
是否处于发送状态
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialDelaySender.Send(TouchSocket.Core.QueueDataBytes)">
<summary>
发送
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialDelaySender.Dispose(System.Boolean)">
<summary>
释放
</summary>
<param name="disposing"></param>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialProperty">
<summary>
串口属性

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Version>2.1.0.4</Version>
<Version>2.1.0.7</Version>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>

View File

@@ -519,8 +519,12 @@ public class OPCDAClient : DisposableObject
{
if (IsConnected)
_logger?.Trace($"{m_server.Host + " - " + m_server.Name} - 断开连接");
checkTimer.Enabled = false;
checkTimer.Stop();
if (checkTimer != null)
{
checkTimer.Enabled = false;
checkTimer.Stop();
}
try
{
m_server?.SafeDispose();

View File

@@ -39,7 +39,7 @@ public class OPCNode
/// </summary>
[Description("检查域")]
public bool CheckDomain { get; set; }
/// <summary>
/// 更新间隔
/// </summary>

View File

@@ -19,7 +19,6 @@ using ThingsGateway.Foundation;
using ThingsGateway.Foundation.Serial;
using TouchSocket.Core;
using TouchSocket.Sockets;
namespace ThingsGateway.DLT645;

View File

@@ -67,6 +67,8 @@ public class ModbusServer : UpLoadBase
var list = Values.ToListWithDequeue();
foreach (var item in list)
{
if (token.IsCancellationRequested)
break;
var type = GetPropertyValue(item.Item2, nameof(ModbusServerVariableProperty.ModbusType));
if (Enum.TryParse<DataTypeEnum>(type, out DataTypeEnum result))
{
@@ -110,7 +112,7 @@ public class ModbusServer : UpLoadBase
_plc?.SafeDispose();
_ModbusTags?.Clear();
_ModbusTags = null;
Values.Clear();
Values?.Clear();
Values = null;
base.Dispose(disposing);
}

View File

@@ -47,7 +47,6 @@ public class MqttServer : UpLoadBase
{
private readonly MqttServerProperty driverPropertys = new();
private readonly ConcurrentDictionary<string, string> IdWithName = new();
private readonly MqttClientVariableProperty variablePropertys = new();
private ConcurrentQueue<DeviceData> _collectDeviceRunTimes = new();
private ConcurrentQueue<VariableData> _collectVariableRunTimes = new();
@@ -365,8 +364,7 @@ public class MqttServer : UpLoadBase
arg.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
IdWithName.AddOrUpdate(arg.ClientId, (a) => arg.UserName, (a, b) => arg.UserName);
LogMessage?.LogInformation(ToString() + "-" + IdWithName[arg.ClientId] + "-客户端已连接成功");
LogMessage?.LogInformation(ToString() + "-" + arg.ClientId + "-客户端已连接成功");
}
private void VariableValueChange(DeviceVariableRunTime collectVariableRunTime)
{

View File

@@ -11,10 +11,6 @@
</Target>
<ItemGroup>
<PackageReference Include="MQTTnet" Version="4.2.1.781" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ThingsGateway.Application\ThingsGateway.Application.csproj" >

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
@@ -56,8 +58,6 @@ public partial class ImportVariable
}
}
[Inject]
IDriverPluginService DriverPluginService { get; set; }
private List<BrowseElement> Selected { get; set; } = new();
@@ -129,7 +129,7 @@ public partial class ImportVariable
Enable = true,
IsLogOut = true,
DevicePropertys = new(),
PluginId = DriverPluginService.GetIdByName(nameof(OPCDAClient)).ToLong(),
PluginId = App.GetService<DriverPluginService>().GetIdByName(nameof(OPCDAClient)).ToLong(),
};
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCName), Value = PLC.OPCNode.OPCName, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCName)).GetCustomAttribute<DevicePropertyAttribute>().Description });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCIP), Value = PLC.OPCNode.OPCIP, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCIP)).GetCustomAttribute<DevicePropertyAttribute>().Description });

View File

@@ -33,7 +33,7 @@ public class OPCDAClientProperty : CollectDriverPropertyBase
/// <summary>
/// 检测重连频率/min
/// </summary>
[DeviceProperty("检测重连频率/min", "")] public int CheckRate { get; set; } = 60000;
[DeviceProperty("检测重连频率/min", "")] public int CheckRate { get; set; } = 10;
/// <summary>
/// 死区
/// </summary>

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Microsoft.AspNetCore.Components;
using Opc.Ua;
@@ -62,8 +64,7 @@ public partial class ImportVariable
}
[Inject]
IDriverPluginService DriverPluginService { get; set; }
private List<ReferenceDescription> Selected { get; set; } = new();
/// <summary>
@@ -155,7 +156,7 @@ public partial class ImportVariable
Enable = true,
IsLogOut = true,
DevicePropertys = new(),
PluginId = DriverPluginService.GetIdByName(nameof(OPCUAClient)).ToLong(),
PluginId = App.GetService<DriverPluginService>().GetIdByName(nameof(OPCUAClient)).ToLong(),
};
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.OPCURL), Value = PLC.OPCNode.OPCUrl, Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.OPCURL)).GetCustomAttribute<DevicePropertyAttribute>().Description });
@@ -236,9 +237,9 @@ public partial class ImportVariable
if (data != null && data.Count > 0)
{
if (isAll)
child.Nodes = await PopulateBranchAsync((NodeId)target.NodeId);
else
child.Nodes = new();
child.Nodes = await PopulateBranchAsync((NodeId)target.NodeId);
else
child.Nodes = new();
}
else
{

View File

@@ -206,7 +206,7 @@ public class OPCUAClient : CollectBase
UserName = driverPropertys.UserName,
Password = driverPropertys.Password,
CheckDomain = driverPropertys.CheckDomain,
};
};
if (_plc == null)
{
_plc = new(LogMessage);

View File

@@ -11,8 +11,6 @@
#endregion
using System.ComponentModel;
using ThingsGateway.Application;
namespace ThingsGateway.OPCUA;

View File

@@ -0,0 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/net6/schemas/v3/furion-schema.json",
}

View File

@@ -7,6 +7,9 @@
<ItemGroup>
<Content Include="Configuration\ManageGatewayConfig.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Configuration\App.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View File

@@ -8,6 +8,12 @@
</PropertyGroup>
<ItemGroup>
<None Remove="WindowsServiceCreate.bat" />
<None Remove="WindowsServiceDelete.bat" />
</ItemGroup>
<ItemGroup>
@@ -24,6 +30,12 @@
<Content Include="Dockerfile">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="WindowsServiceCreate.bat">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="WindowsServiceDelete.bat">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

View File

@@ -0,0 +1,5 @@
cd ..
sc create ThingsGateway binPath=%~dp0ThingsGateway.Web.Entry.exe start= auto
sc description ThingsGateway "ThingsGateway<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
Net Start ThingsGateway
pause

View File

@@ -0,0 +1,3 @@
net stop ThingsGateway
sc delete ThingsGateway
pause

View File

@@ -6,7 +6,7 @@ export const language = ["en","zh"];
export const removeDefaultStopWordFilter = false;
export const removeDefaultStemmer = false;
export { default as Mark } from "E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\mark.js\\dist\\mark.js"
export const searchIndexUrl = "search-index{dir}.json?_=b540398d";
export const searchIndexUrl = "search-index{dir}.json?_=b46d0594";
export const searchResultLimits = 8;
export const searchResultContextMaxLength = 50;
export const explicitSearchResultPath = true;

View File

@@ -224,18 +224,18 @@
"179": {
"js": [
{
"file": "assets/js/main.b87012d2.js",
"hash": "431093d97c62ad32",
"publicPath": "/thingsgateway-docs/assets/js/main.b87012d2.js"
"file": "assets/js/main.985baeb2.js",
"hash": "3c39431d0c60f86d",
"publicPath": "/thingsgateway-docs/assets/js/main.985baeb2.js"
}
]
},
"229": {
"js": [
{
"file": "assets/js/39f79d48.58f16413.js",
"hash": "ba5629f1b6730241",
"publicPath": "/thingsgateway-docs/assets/js/39f79d48.58f16413.js"
"file": "assets/js/39f79d48.61b5661b.js",
"hash": "dc581ebbf04e3195",
"publicPath": "/thingsgateway-docs/assets/js/39f79d48.61b5661b.js"
}
]
},
@@ -296,9 +296,9 @@
"1303": {
"js": [
{
"file": "assets/js/runtime~main.b83c840d.js",
"hash": "dfb4bebe3fe21c9f",
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.b83c840d.js"
"file": "assets/js/runtime~main.00620874.js",
"hash": "d5db7c654e6f44e6",
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.00620874.js"
}
]
},
@@ -323,9 +323,9 @@
"1822": {
"js": [
{
"file": "assets/js/f05a39b7.1a2db08f.js",
"hash": "25429336b0e231c1",
"publicPath": "/thingsgateway-docs/assets/js/f05a39b7.1a2db08f.js"
"file": "assets/js/f05a39b7.0ae3d033.js",
"hash": "43e5b3451f089837",
"publicPath": "/thingsgateway-docs/assets/js/f05a39b7.0ae3d033.js"
}
]
},

View File

@@ -12,8 +12,8 @@
"tags": [],
"version": "current",
"lastUpdatedBy": "Kimdiego2098",
"lastUpdatedAt": 1692963213,
"formattedLastUpdatedAt": "Aug 25, 2023",
"lastUpdatedAt": 1693444679,
"formattedLastUpdatedAt": "Aug 31, 2023",
"frontMatter": {
"id": "plugindlt6452007",
"title": "DLT645-2007采集插件"

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More