This commit is contained in:
Diego
2025-07-04 08:36:37 +08:00
parent 1aa0df6339
commit 6ae44ccf58
11 changed files with 135 additions and 32 deletions

View File

@@ -1,10 +1,10 @@
<Project>
<PropertyGroup>
<PluginVersion>10.9.16</PluginVersion>
<ProPluginVersion>10.9.16</ProPluginVersion>
<AuthenticationVersion>2.9.5</AuthenticationVersion>
<SourceGeneratorVersion>10.9.5</SourceGeneratorVersion>
<PluginVersion>10.9.17</PluginVersion>
<ProPluginVersion>10.9.17</ProPluginVersion>
<AuthenticationVersion>2.9.7</AuthenticationVersion>
<SourceGeneratorVersion>10.9.7</SourceGeneratorVersion>
<NET8Version>8.0.17</NET8Version>
<NET9Version>9.0.6</NET9Version>
<SatelliteResourceLanguages>zh-Hans;en-US</SatelliteResourceLanguages>

View File

@@ -748,7 +748,7 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
var num = Drivers.Count;
foreach (var driver in Drivers.Select(a => a.Value).ToList())
foreach (var driver in Drivers.Select(a => a.Value).Where(a => a != null).ToList())
{
try
{

View File

@@ -8,6 +8,8 @@
// QQ群605534569
//------------------------------------------------------------------------------
using ThingsGateway.Authentication;
namespace ThingsGateway.Gateway.Application;
internal static class ManageHelper
@@ -21,26 +23,31 @@ internal static class ManageHelper
public static void CheckChannelCount(int addCount)
{
if (GlobalData.Channels.Count + addCount > ManageHelper.ChannelThreadOptions.MaxChannelCount)
var data = GlobalData.Channels.Count + addCount;
ProAuthentication.TryGetAuthorizeInfo(out var authorizeInfo);
if (data > ManageHelper.ChannelThreadOptions.MaxChannelCount || data > authorizeInfo?.MaxChannelCount)
{
throw new Exception($"The number of channels exceeds the limit {ManageHelper.ChannelThreadOptions.MaxChannelCount}");
throw new Exception($"The number of channels exceeds the limit {Math.Min(ManageHelper.ChannelThreadOptions.MaxChannelCount, authorizeInfo?.MaxChannelCount ?? 0)}");
}
}
public static void CheckDeviceCount(int addCount)
{
if (GlobalData.Devices.Count + addCount > ManageHelper.ChannelThreadOptions.MaxDeviceCount)
var data = GlobalData.Devices.Count + addCount;
ProAuthentication.TryGetAuthorizeInfo(out var authorizeInfo);
if (data > ManageHelper.ChannelThreadOptions.MaxDeviceCount || data > authorizeInfo?.MaxDeviceCount)
{
throw new Exception($"The number of devices exceeds the limit {ManageHelper.ChannelThreadOptions.MaxDeviceCount}");
throw new Exception($"The number of devices exceeds the limit {Math.Min(ManageHelper.ChannelThreadOptions.MaxDeviceCount, authorizeInfo?.MaxDeviceCount ?? 0)}");
}
}
public static void CheckVariableCount(int addCount)
{
if (GlobalData.IdVariables.Count + addCount > ManageHelper.ChannelThreadOptions.MaxVariableCount)
var data = GlobalData.IdVariables.Count + addCount;
ProAuthentication.TryGetAuthorizeInfo(out var authorizeInfo);
if (data > ManageHelper.ChannelThreadOptions.MaxVariableCount || data > authorizeInfo?.MaxVariableCount)
{
throw new Exception($"The number of variables exceeds the limit {ManageHelper.ChannelThreadOptions.MaxVariableCount}");
throw new Exception($"The number of variables exceeds the limit {Math.Min(ManageHelper.ChannelThreadOptions.MaxVariableCount, authorizeInfo?.MaxVariableCount ?? 0)}");
}
}

View File

@@ -26,7 +26,10 @@
"RegisterStatus": "RegisterStatus",
"Unauthorized": "Unauthorized",
"Unregister": "Unregister",
"UUID": "UUID"
"UUID": "UUID",
"MaxChannelCount": "MaxChannelCount",
"MaxDeviceCount": "MaxDeviceCount",
"MaxVariableCount": "MaxVariableCount"
},
"ThingsGateway.Gateway.Razor._Imports": {

View File

@@ -24,7 +24,10 @@
"RegisterStatus": "注册状态",
"Unauthorized": "未授权",
"Unregister": "取消注册",
"UUID": "唯一编码"
"UUID": "唯一编码",
"MaxChannelCount": "最大通道数量",
"MaxDeviceCount": "最大设备数量",
"MaxVariableCount": "最大变量数量"
},
"ThingsGateway.Gateway.Razor._Imports": {

View File

@@ -20,3 +20,4 @@ public static partial class GatewayMapper
}

View File

@@ -0,0 +1,54 @@
// <auto-generated />
#nullable enable
namespace ThingsGateway.Gateway.Razor
{
public static class TreeViewItemMapper
{
public static global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> AdaptListTreeViewItemChannelDeviceTreeItem(this global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> src, global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> parent = null)
{
var target = new global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>>(src.Count);
foreach (var item in src)
{
target.Add(MapToTreeViewItemOfChannelDeviceTreeItem(item, parent));
}
return target;
}
private static global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> MapToTreeViewItemOfChannelDeviceTreeItem(global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> source, global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> parent)
{
var target = new global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>(source.Value);
target.CheckedState = source.CheckedState;
target.Items = AdaptListTreeViewItemChannelDeviceTreeItem(source.Items.ToList(), target);
if (source.Parent != null && parent != null)
{
target.Parent = parent;
}
else
{
target.Parent = null;
}
target.Text = source.Text;
target.Icon = source.Icon;
target.ExpandIcon = source.ExpandIcon;
target.CssClass = source.CssClass;
target.IsDisabled = source.IsDisabled;
target.IsActive = source.IsActive;
target.Template = source.Template;
if (source.Value != null)
{
target.Value = source.Value;
}
else
{
target.Value = null;
}
target.IsExpand = source.IsExpand;
target.HasChildren = source.HasChildren;
return target;
}
}
}

View File

@@ -8,7 +8,7 @@
<div class="listtree-view">
<div class="d-flex align-items-center">
<RadioList class="m-2" IsButton="true" AutoSelectFirstWhenValueIsNull="false" TValue="ShowTypeEnum?" ValueExpression=@(()=> ShowType ) Value="ShowType" ValueChanged="OnShowTypeChanged" ShowLabel="false" />
<RadioList class="m-2" IsButton="true" AutoSelectFirstWhenValueIsNull="false" TValue="ShowTypeEnum?" ValueExpression=@(() => ShowType) Value="ShowType" ValueChanged="OnShowTypeChanged" ShowLabel="false" />
<SpinnerComponent @ref=Spinner></SpinnerComponent>
</div>
@@ -16,25 +16,25 @@
<span style="color:var(--bs-body-color)" class="text-h6 mb-2">@GatewayLocalizer["DeviceList"]</span>
<ContextMenuZone title="Right click operation">
<TreeView TItem="ChannelDeviceTreeItem" Items="Items" ShowIcon="false" ShowSearch IsAccordion=false IsVirtualize="true" OnTreeItemClick="OnTreeItemClick" OnSearchAsync="OnClickSearch" ModelEqualityComparer=ModelEqualityComparer>
<TreeView TItem="ChannelDeviceTreeItem" Items="Items" ShowIcon="false" ShowSearch IsAccordion=false IsVirtualize="true" OnTreeItemClick="OnTreeItemClick" OnSearchAsync="OnClickSearch" ModelEqualityComparer=ModelEqualityComparer>
</TreeView>
<ContextMenu style="max-height:800px" class="tgTree" OnBeforeShowCallback="OnBeforeShowCallback">
@if (SelectModel != null)
{
<ContextMenuItem Icon="fa-solid fa-plus" Disabled="(SelectModel.ChannelDevicePluginType >ChannelDevicePluginTypeEnum.Channel||!AuthorizeButton(AdminOperConst.Add))" Text="@GatewayLocalizer["AddChannel"]" OnClick=@((a,b)=>EditChannel(a,b,ItemChangedType.Add))></ContextMenuItem>
<ContextMenuItem Icon="fa-solid fa-plus" Disabled="(SelectModel.ChannelDevicePluginType > ChannelDevicePluginTypeEnum.Channel || !AuthorizeButton(AdminOperConst.Add))" Text="@GatewayLocalizer["AddChannel"]" OnClick=@((a, b) => EditChannel(a, b, ItemChangedType.Add))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Disabled="(SelectModel.ChannelDevicePluginType >=ChannelDevicePluginTypeEnum.Channel||!AuthorizeButton(AdminOperConst.Edit))" Text="@GatewayLocalizer["BatchEditChannel"]" OnClick=@((a,b)=>BatchEditChannel(a,b))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Disabled="(SelectModel.ChannelDevicePluginType >= ChannelDevicePluginTypeEnum.Channel || !AuthorizeButton(AdminOperConst.Edit))" Text="@GatewayLocalizer["BatchEditChannel"]" OnClick=@((a, b) => BatchEditChannel(a, b))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Disabled="(!AuthorizeButton(AdminOperConst.Add))" Text="@GatewayLocalizer["ExcelChannel"]" OnClick=@((a,b)=>ExcelChannel(a,b))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Disabled="(!AuthorizeButton(AdminOperConst.Add))" Text="@GatewayLocalizer["ExcelChannel"]" OnClick=@((a, b) => ExcelChannel(a, b))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Disabled="(SelectModel.ChannelDevicePluginType !=ChannelDevicePluginTypeEnum.Channel||!AuthorizeButton(AdminOperConst.Edit))" Text="@GatewayLocalizer["UpdateChannel"]" OnClick=@((a,b)=>EditChannel(a,b,ItemChangedType.Update))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Disabled="(SelectModel.ChannelDevicePluginType != ChannelDevicePluginTypeEnum.Channel || !AuthorizeButton(AdminOperConst.Edit))" Text="@GatewayLocalizer["UpdateChannel"]" OnClick=@((a, b) => EditChannel(a, b, ItemChangedType.Update))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-copy" Disabled="(SelectModel.ChannelDevicePluginType !=ChannelDevicePluginTypeEnum.Channel||!AuthorizeButton(AdminOperConst.Add))" Text="@GatewayLocalizer["CopyChannel"]" OnClick=@((a,b)=>CopyChannel(a,b))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-copy" Disabled="(SelectModel.ChannelDevicePluginType != ChannelDevicePluginTypeEnum.Channel || !AuthorizeButton(AdminOperConst.Add))" Text="@GatewayLocalizer["CopyChannel"]" OnClick=@((a, b) => CopyChannel(a, b))></ContextMenuItem>
<ContextMenuItem Icon="fa-solid fa-xmark" Text="@GatewayLocalizer["DeleteChannel"]" Disabled="(SelectModel.ChannelDevicePluginType ==ChannelDevicePluginTypeEnum.Device||!AuthorizeButton(AdminOperConst.Delete))" OnClick="DeleteChannel"></ContextMenuItem>
<ContextMenuItem Icon="fa-solid fa-xmark" Text="@GatewayLocalizer["DeleteChannel"]" Disabled="(SelectModel.ChannelDevicePluginType == ChannelDevicePluginTypeEnum.Device || !AuthorizeButton(AdminOperConst.Delete))" OnClick="DeleteChannel"></ContextMenuItem>
<ContextMenuItem Icon="fas fa-file-export" Text="@GatewayLocalizer["ExportChannel"]"
Disabled=@(SelectModel.ChannelDevicePluginType ==ChannelDevicePluginTypeEnum.Device||!AuthorizeButton("导出"))
@@ -44,16 +44,16 @@
<ContextMenuDivider></ContextMenuDivider>
<ContextMenuItem Disabled="(SelectModel.ChannelDevicePluginType <ChannelDevicePluginTypeEnum.Channel)||!AuthorizeButton(AdminOperConst.Add)" Icon="fa-solid fa-plus device" Text="@GatewayLocalizer["AddDevice"]" OnClick=@((a,b)=>EditDevice(a,b,ItemChangedType.Add))></ContextMenuItem>
<ContextMenuItem Disabled="(SelectModel.ChannelDevicePluginType < ChannelDevicePluginTypeEnum.Channel) || !AuthorizeButton(AdminOperConst.Add)" Icon="fa-solid fa-plus device" Text="@GatewayLocalizer["AddDevice"]" OnClick=@((a, b) => EditDevice(a, b, ItemChangedType.Add))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Text="@GatewayLocalizer["BatchEditDevice"]" Disabled="(SelectModel.ChannelDevicePluginType >=ChannelDevicePluginTypeEnum.Device)||!AuthorizeButton(AdminOperConst.Edit)" OnClick=@((a,b)=>BatchEditDevice(a,b))></ContextMenuItem>
<ContextMenuItem Icon="fa-regular fa-pen-to-square" Text="@GatewayLocalizer["BatchEditDevice"]" Disabled="(SelectModel.ChannelDevicePluginType >= ChannelDevicePluginTypeEnum.Device) || !AuthorizeButton(AdminOperConst.Edit)" OnClick=@((a, b) => BatchEditDevice(a, b))></ContextMenuItem>
<ContextMenuItem Disabled="!AuthorizeButton(AdminOperConst.Add)" Icon="fa-solid fa-plus" Text="@GatewayLocalizer["ExcelDevice"]" OnClick=@((a,b)=>ExcelDevice(a,b))></ContextMenuItem>
<ContextMenuItem Disabled="!AuthorizeButton(AdminOperConst.Add)" Icon="fa-solid fa-plus" Text="@GatewayLocalizer["ExcelDevice"]" OnClick=@((a, b) => ExcelDevice(a, b))></ContextMenuItem>
<ContextMenuItem Disabled="(SelectModel.ChannelDevicePluginType !=ChannelDevicePluginTypeEnum.Device)||!AuthorizeButton(AdminOperConst.Edit)" Icon="fa-regular fa-pen-to-square" Text="@GatewayLocalizer["UpdateDevice"]" OnClick=@((a,b)=>EditDevice(a,b,ItemChangedType.Update))></ContextMenuItem>
<ContextMenuItem Disabled="(SelectModel.ChannelDevicePluginType != ChannelDevicePluginTypeEnum.Device) || !AuthorizeButton(AdminOperConst.Edit)" Icon="fa-regular fa-pen-to-square" Text="@GatewayLocalizer["UpdateDevice"]" OnClick=@((a, b) => EditDevice(a, b, ItemChangedType.Update))></ContextMenuItem>
<ContextMenuItem Disabled="(SelectModel.ChannelDevicePluginType !=ChannelDevicePluginTypeEnum.Device)||!AuthorizeButton(AdminOperConst.Add)" Icon="fa-regular fa-pen-to-square" Text="@GatewayLocalizer["CopyDevice"]" OnClick=@((a,b)=>CopyDevice(a,b))></ContextMenuItem>
<ContextMenuItem Disabled="(SelectModel.ChannelDevicePluginType != ChannelDevicePluginTypeEnum.Device) || !AuthorizeButton(AdminOperConst.Add)" Icon="fa-regular fa-pen-to-square" Text="@GatewayLocalizer["CopyDevice"]" OnClick=@((a, b) => CopyDevice(a, b))></ContextMenuItem>
<ContextMenuItem Icon="fa-solid fa-xmark" Disabled="(!AuthorizeButton(AdminOperConst.Delete))" Text="@GatewayLocalizer["DeleteDevice"]" OnClick="DeleteDevice"></ContextMenuItem>

View File

@@ -1259,7 +1259,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
}
}
Items = ZItem;
Items = ZItem.AdaptListTreeViewItemChannelDeviceTreeItem();
ChannelRuntimeDispatchService.Subscribe(Refresh);
scheduler = new SmartTriggerScheduler(Notify, TimeSpan.FromMilliseconds(3000));
@@ -1375,7 +1375,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
{
}
}
Items = ZItem;
Items = ZItem.AdaptListTreeViewItemChannelDeviceTreeItem();
return Items;
}
else
@@ -1459,7 +1459,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
}
}
Items = ZItem;
Items = ZItem.AdaptListTreeViewItemChannelDeviceTreeItem();
return Items;
}

View File

@@ -40,7 +40,7 @@
</label>
<label class="form-control">
@(AuthorizeInfo?.Auth==true ? Localizer["Authorized"] : Localizer["Unauthorized"])
@(AuthorizeInfo?.Auth == true ? Localizer["Authorized"] : Localizer["Unauthorized"])
</label>
</div>
</div>
@@ -75,6 +75,41 @@
</label>
</div>
<div class="col-12 col-sm-12">
<label class="form-label">
@Localizer["MaxChannelCount"]
</label>
<label class="form-control">
@AuthorizeInfo?.MaxChannelCount
</label>
</div>
<div class="col-12 col-sm-12">
<label class="form-label">
@Localizer["MaxDeviceCount"]
</label>
<label class="form-control">
@AuthorizeInfo?.MaxDeviceCount
</label>
</div>
<div class="col-12 col-sm-12">
<label class="form-label">
@Localizer["MaxVariableCount"]
</label>
<label class="form-control">
@AuthorizeInfo?.MaxVariableCount
</label>
</div>
</div>
}

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>10.9.16</Version>
<Version>10.9.17</Version>
</PropertyGroup>
<ItemGroup>