mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-28 14:13:59 +08:00
feat: 支持变量低内存导出
This commit is contained in:
@@ -90,8 +90,8 @@
|
|||||||
<h6> @((100 - (availableMemory * 100.00 / memory)).ToString("F2") + " %") </h6>
|
<h6> @((100 - (availableMemory * 100.00 / memory)).ToString("F2") + " %") </h6>
|
||||||
|
|
||||||
<span> @Localizer["WorkingSet"] <i> @(HardwareJob.HardwareInfo.WorkingSet + " MB")</i></span>
|
<span> @Localizer["WorkingSet"] <i> @(HardwareJob.HardwareInfo.WorkingSet + " MB")</i></span>
|
||||||
<span> @Localizer["AvailableMemory"] <i> @((availableMemory / 1024.00 / 1024 / 1024).ToString("F2") + " GB")</i></span>
|
<span> @Localizer["AvailableMemory"] <i> @((availableMemory / 1024.00 / 1024).ToString("F2") + " GB")</i></span>
|
||||||
<span> @Localizer["TotalMemory"] <i> @((memory / 1024.00 / 1024 / 1024).ToString("F2") + " GB")</i></span>
|
<span> @Localizer["TotalMemory"] <i> @((memory / 1024.00 / 1024).ToString("F2") + " GB")</i></span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</Circle>
|
</Circle>
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class Startup : AppStartup
|
|||||||
.AddHubOptions(options =>
|
.AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize = 32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
@@ -126,7 +126,7 @@ public class Startup : AppStartup
|
|||||||
}).AddHubOptions(options =>
|
}).AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize = 32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
|
|||||||
@@ -88,11 +88,11 @@ public class MachineInfo : IExtend
|
|||||||
[DisplayName("磁盘序列号")]
|
[DisplayName("磁盘序列号")]
|
||||||
public String? DiskID { get; set; }
|
public String? DiskID { get; set; }
|
||||||
|
|
||||||
/// <summary>内存总量。单位Byte</summary>
|
/// <summary>内存总量。单位KB</summary>
|
||||||
[DisplayName("内存总量")]
|
[DisplayName("内存总量")]
|
||||||
public UInt64 Memory { get; set; }
|
public UInt64 Memory { get; set; }
|
||||||
|
|
||||||
/// <summary>可用内存。单位Byte</summary>
|
/// <summary>可用内存。单位KB</summary>
|
||||||
[DisplayName("可用内存")]
|
[DisplayName("可用内存")]
|
||||||
public UInt64 AvailableMemory { get; set; }
|
public UInt64 AvailableMemory { get; set; }
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ public class MachineInfo : IExtend
|
|||||||
#if NETFRAMEWORK || WINDOWS
|
#if NETFRAMEWORK || WINDOWS
|
||||||
{
|
{
|
||||||
var ci = new Microsoft.VisualBasic.Devices.ComputerInfo();
|
var ci = new Microsoft.VisualBasic.Devices.ComputerInfo();
|
||||||
Memory = ci.TotalPhysicalMemory;
|
Memory = (ulong)(ci.TotalPhysicalMemory / 1024.0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -557,7 +557,7 @@ public class MachineInfo : IExtend
|
|||||||
//if (dic2.TryGetValue("Model Name", out str)) Product = str;
|
//if (dic2.TryGetValue("Model Name", out str)) Product = str;
|
||||||
if (dic.TryGetValue("Model Identifier", out var str)) Product = str;
|
if (dic.TryGetValue("Model Identifier", out var str)) Product = str;
|
||||||
if (dic.TryGetValue("Processor Name", out str)) Processor = str;
|
if (dic.TryGetValue("Processor Name", out str)) Processor = str;
|
||||||
if (dic.TryGetValue("Memory", out str)) Memory = (UInt64)str.TrimEnd("GB").Trim().ToLong() * 1024 * 1024 * 1024;
|
if (dic.TryGetValue("Memory", out str)) Memory = (UInt64)str.TrimEnd("GB").Trim().ToLong() * 1024 * 1024;
|
||||||
if (dic.TryGetValue("Serial Number (system)", out str)) Serial = str;
|
if (dic.TryGetValue("Serial Number (system)", out str)) Serial = str;
|
||||||
if (dic.TryGetValue("Hardware UUID", out str)) UUID = str;
|
if (dic.TryGetValue("Hardware UUID", out str)) UUID = str;
|
||||||
if (dic.TryGetValue("Processor Name", out str)) Processor = str;
|
if (dic.TryGetValue("Processor Name", out str)) Processor = str;
|
||||||
@@ -594,8 +594,8 @@ public class MachineInfo : IExtend
|
|||||||
ms.Init();
|
ms.Init();
|
||||||
if (GlobalMemoryStatusEx(ref ms))
|
if (GlobalMemoryStatusEx(ref ms))
|
||||||
{
|
{
|
||||||
Memory = ms.ullTotalPhys;
|
Memory = (ulong)(ms.ullTotalPhys / 1024.0);
|
||||||
AvailableMemory = ms.ullAvailPhys;
|
AvailableMemory = (ulong)(ms.ullAvailPhys / 1024.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetSystemTimes(out var idleTime, out var kernelTime, out var userTime);
|
GetSystemTimes(out var idleTime, out var kernelTime, out var userTime);
|
||||||
@@ -695,15 +695,15 @@ public class MachineInfo : IExtend
|
|||||||
if (dic != null)
|
if (dic != null)
|
||||||
{
|
{
|
||||||
if (dic.TryGetValue("MemTotal", out var str) && !str.IsNullOrEmpty())
|
if (dic.TryGetValue("MemTotal", out var str) && !str.IsNullOrEmpty())
|
||||||
Memory = (UInt64)str.TrimEnd(" kB").ToInt() * 1024;
|
Memory = (UInt64)str.TrimEnd(" kB").ToLong();
|
||||||
|
|
||||||
if (dic.TryGetValue("MemAvailable", out str) && !str.IsNullOrEmpty())
|
if (dic.TryGetValue("MemAvailable", out str) && !str.IsNullOrEmpty())
|
||||||
AvailableMemory = (UInt64)str.TrimEnd(" kB").ToInt() * 1024;
|
AvailableMemory = (UInt64)str.TrimEnd(" kB").ToLong();
|
||||||
else if (dic.TryGetValue("MemFree", out str) && !str.IsNullOrEmpty())
|
else if (dic.TryGetValue("MemFree", out str) && !str.IsNullOrEmpty())
|
||||||
AvailableMemory =
|
AvailableMemory =
|
||||||
(UInt64)(str.TrimEnd(" kB").ToInt() +
|
(UInt64)(str.TrimEnd(" kB").ToLong() +
|
||||||
dic["Buffers"]?.TrimEnd(" kB").ToInt() ?? 0 +
|
dic["Buffers"]?.TrimEnd(" kB").ToLong() ?? 0 +
|
||||||
dic["Cached"]?.TrimEnd(" kB").ToInt() ?? 0) * 1024;
|
dic["Cached"]?.TrimEnd(" kB").ToLong() ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A2/A4温度获取,Buildroot,CPU温度和主板温度
|
// A2/A4温度获取,Buildroot,CPU温度和主板温度
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ public abstract class Logger : ILog
|
|||||||
sb.AppendFormat("#CPU: {0}\r\n", Environment.ProcessorCount);
|
sb.AppendFormat("#CPU: {0}\r\n", Environment.ProcessorCount);
|
||||||
if (mi != null)
|
if (mi != null)
|
||||||
{
|
{
|
||||||
sb.AppendFormat("#Memory: {0:n0}M/{1:n0}M\r\n", mi.AvailableMemory / 1024 / 1024, mi.Memory / 1024 / 1024);
|
sb.AppendFormat("#Memory: {0:n0}M/{1:n0}M\r\n", mi.AvailableMemory / 1024, mi.Memory / 1024);
|
||||||
sb.AppendFormat("#Processor: {0}\r\n", mi.Processor);
|
sb.AppendFormat("#Processor: {0}\r\n", mi.Processor);
|
||||||
if (!mi.Product.IsNullOrEmpty()) sb.AppendFormat("#Product: {0} / {1}\r\n", mi.Product, mi.Vendor);
|
if (!mi.Product.IsNullOrEmpty()) sb.AppendFormat("#Product: {0} / {1}\r\n", mi.Product, mi.Vendor);
|
||||||
if (mi.Temperature > 0) sb.AppendFormat("#Temperature: {0}\r\n", mi.Temperature);
|
if (mi.Temperature > 0) sb.AppendFormat("#Temperature: {0}\r\n", mi.Temperature);
|
||||||
|
|||||||
@@ -44,3 +44,14 @@ public class ImportPreviewOutput<T> : ImportPreviewOutputBase where T : class
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, T> Data { get; set; } = new();
|
public Dictionary<string, T> Data { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 导入预览
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
public class ImportPreviewListOutput<T> : ImportPreviewOutputBase where T : class
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据
|
||||||
|
/// </summary>
|
||||||
|
public List<T> Data { get; set; } = new();
|
||||||
|
}
|
||||||
|
|||||||
@@ -683,7 +683,7 @@ namespace ThingsGateway.SqlSugar
|
|||||||
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
||||||
var columns = UtilMethods.GetColumnInfo(dr);
|
var columns = UtilMethods.GetColumnInfo(dr);
|
||||||
var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
||||||
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate("cacheKey", () =>
|
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () =>
|
||||||
{
|
{
|
||||||
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
||||||
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
||||||
@@ -703,15 +703,15 @@ namespace ThingsGateway.SqlSugar
|
|||||||
this.Context.Ado.Close();
|
this.Context.Ado.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public IEnumerable<T> ForEachDataReader()
|
public IEnumerable<T> GetEnumerable()
|
||||||
{
|
{
|
||||||
var queryable = this.Clone();
|
var queryable = this.Clone();
|
||||||
var sql = queryable.ToSql();
|
var sql = queryable.ToSql();
|
||||||
var dr = this.Context.Ado.GetDataReader(sql.Key, sql.Value);
|
var dr = this.Context.Ado.GetDataReader(sql.Key, sql.Value);
|
||||||
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
||||||
var columns = UtilMethods.GetColumnInfo(dr);
|
var columns = UtilMethods.GetColumnInfo(dr);
|
||||||
var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
var cacheKey = "GetEnumerable" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
||||||
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate("cacheKey", () =>
|
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () =>
|
||||||
{
|
{
|
||||||
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
||||||
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
||||||
@@ -743,7 +743,7 @@ namespace ThingsGateway.SqlSugar
|
|||||||
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
||||||
var columns = UtilMethods.GetColumnInfo(dr);
|
var columns = UtilMethods.GetColumnInfo(dr);
|
||||||
var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
||||||
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate("cacheKey", () =>
|
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () =>
|
||||||
{
|
{
|
||||||
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
||||||
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
||||||
@@ -775,8 +775,8 @@ namespace ThingsGateway.SqlSugar
|
|||||||
var dr = await Context.Ado.GetDataReaderAsync(sql.Key, sql.Value).ConfigureAwait(false);
|
var dr = await Context.Ado.GetDataReaderAsync(sql.Key, sql.Value).ConfigureAwait(false);
|
||||||
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
|
||||||
var columns = UtilMethods.GetColumnInfo(dr);
|
var columns = UtilMethods.GetColumnInfo(dr);
|
||||||
var cacheKey = "ForEachDataReader" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
var cacheKey = "GetAsyncEnumerable" + typeof(T).GetHashCode() + string.Join(",", columns.Select(it => it.Item1 + it.Item2.Name + "_"));
|
||||||
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate("cacheKey", () =>
|
IDataReaderEntityBuilder<T> entytyList = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () =>
|
||||||
{
|
{
|
||||||
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
var cacheResult = new IDataReaderEntityBuilder<T>(this.Context, dr,
|
||||||
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
columns.Select(it => it.Item1).ToList()).CreateBuilder(typeof(T));
|
||||||
@@ -784,7 +784,6 @@ namespace ThingsGateway.SqlSugar
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using (dr)
|
using (dr)
|
||||||
{
|
{
|
||||||
while (dr.Read())
|
while (dr.Read())
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace ThingsGateway.SqlSugar
|
|||||||
NavISugarQueryable<T> Includes<TReturn1, TReturn2, TReturn3>(Expression<Func<T, List<TReturn1>>> include1, Expression<Func<TReturn1, TReturn2>> include2, Expression<Func<TReturn2, TReturn3>> include3);
|
NavISugarQueryable<T> Includes<TReturn1, TReturn2, TReturn3>(Expression<Func<T, List<TReturn1>>> include1, Expression<Func<TReturn1, TReturn2>> include2, Expression<Func<TReturn2, TReturn3>> include3);
|
||||||
NavISugarQueryable<T> Includes<TReturn1, TReturn2, TReturn3>(Expression<Func<T, TReturn1>> include1, Expression<Func<TReturn1, List<TReturn2>>> include2, Expression<Func<TReturn2, List<TReturn3>>> include3);
|
NavISugarQueryable<T> Includes<TReturn1, TReturn2, TReturn3>(Expression<Func<T, TReturn1>> include1, Expression<Func<TReturn1, List<TReturn2>>> include2, Expression<Func<TReturn2, List<TReturn3>>> include3);
|
||||||
IAsyncEnumerable<T> GetAsyncEnumerable();
|
IAsyncEnumerable<T> GetAsyncEnumerable();
|
||||||
IEnumerable<T> ForEachDataReader();
|
IEnumerable<T> GetEnumerable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PluginVersion>10.9.15</PluginVersion>
|
<PluginVersion>10.9.16</PluginVersion>
|
||||||
<ProPluginVersion>10.9.14</ProPluginVersion>
|
<ProPluginVersion>10.9.16</ProPluginVersion>
|
||||||
<AuthenticationVersion>2.9.5</AuthenticationVersion>
|
<AuthenticationVersion>2.9.5</AuthenticationVersion>
|
||||||
<SourceGeneratorVersion>10.9.5</SourceGeneratorVersion>
|
<SourceGeneratorVersion>10.9.5</SourceGeneratorVersion>
|
||||||
<NET8Version>8.0.17</NET8Version>
|
<NET8Version>8.0.17</NET8Version>
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ public static partial class GatewayMapper
|
|||||||
|
|
||||||
[MapProperty(nameof(Variable.InitValue), nameof(VariableRuntime.Value))]
|
[MapProperty(nameof(Variable.InitValue), nameof(VariableRuntime.Value))]
|
||||||
public static partial VariableRuntime AdaptVariableRuntime(this Variable src);
|
public static partial VariableRuntime AdaptVariableRuntime(this Variable src);
|
||||||
|
|
||||||
public static partial List<Variable> AdaptListVariable(this IEnumerable<Variable> src);
|
public static partial List<Variable> AdaptListVariable(this IEnumerable<Variable> src);
|
||||||
|
|
||||||
public static partial DeviceRuntime AdaptDeviceRuntime(this Device src);
|
public static partial DeviceRuntime AdaptDeviceRuntime(this Device src);
|
||||||
|
|||||||
@@ -323,8 +323,8 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
|||||||
{
|
{
|
||||||
if (item.Key == ExportString.ChannelName)
|
if (item.Key == ExportString.ChannelName)
|
||||||
{
|
{
|
||||||
var channelImports = ((ImportPreviewOutput<Channel>)item.Value).Data;
|
var channelImports = ((ImportPreviewListOutput<Channel>)item.Value).Data;
|
||||||
channels = channelImports.Select(a => a.Value).ToList();
|
channels = channelImports;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,8 +334,16 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
|||||||
ManageHelper.CheckChannelCount(insertData.Count);
|
ManageHelper.CheckChannelCount(insertData.Count);
|
||||||
|
|
||||||
using var db = GetDB();
|
using var db = GetDB();
|
||||||
await db.BulkCopyAsync(insertData, 100000).ConfigureAwait(false);
|
if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory > 2 * 1024 * 1024)
|
||||||
await db.BulkUpdateAsync(upData, 100000).ConfigureAwait(false);
|
{
|
||||||
|
await db.BulkCopyAsync(insertData, 200000).ConfigureAwait(false);
|
||||||
|
await db.BulkUpdateAsync(upData, 200000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await db.BulkCopyAsync(insertData, 10000).ConfigureAwait(false);
|
||||||
|
await db.BulkUpdateAsync(upData, 10000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
DeleteChannelFromCache();
|
DeleteChannelFromCache();
|
||||||
return channels.Select(a => a.Id).ToHashSet();
|
return channels.Select(a => a.Id).ToHashSet();
|
||||||
}
|
}
|
||||||
@@ -352,11 +360,10 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
|||||||
//导入检验结果
|
//导入检验结果
|
||||||
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
||||||
//设备页
|
//设备页
|
||||||
ImportPreviewOutput<Channel> channelImportPreview = new();
|
|
||||||
foreach (var sheetName in sheetNames)
|
foreach (var sheetName in sheetNames)
|
||||||
{
|
{
|
||||||
var rows = MiniExcel.Query(path, useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
|
var rows = MiniExcel.Query(path, useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
|
||||||
SetChannelData(dataScope, channelDicts, ImportPreviews, channelImportPreview, sheetName, rows);
|
SetChannelData(dataScope, channelDicts, ImportPreviews, sheetName, rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImportPreviews;
|
return ImportPreviews;
|
||||||
@@ -367,16 +374,15 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetChannelData(HashSet<long>? dataScope, Dictionary<string, Channel> channelDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, ImportPreviewOutput<Channel> channelImportPreview, string sheetName, IEnumerable<IDictionary<string, object>> rows)
|
public void SetChannelData(HashSet<long>? dataScope, Dictionary<string, Channel> channelDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, string sheetName, IEnumerable<IDictionary<string, object>> rows)
|
||||||
{
|
{
|
||||||
#region sheet
|
#region sheet
|
||||||
|
|
||||||
if (sheetName == ExportString.ChannelName)
|
if (sheetName == ExportString.ChannelName)
|
||||||
{
|
{
|
||||||
int row = 1;
|
int row = 1;
|
||||||
ImportPreviewOutput<Channel> importPreviewOutput = new();
|
ImportPreviewListOutput<Channel> importPreviewOutput = new();
|
||||||
ImportPreviews.Add(sheetName, importPreviewOutput);
|
ImportPreviews.Add(sheetName, importPreviewOutput);
|
||||||
channelImportPreview = importPreviewOutput;
|
|
||||||
List<Channel> channels = new();
|
List<Channel> channels = new();
|
||||||
var type = typeof(Channel);
|
var type = typeof(Channel);
|
||||||
// 获取目标类型的所有属性,并根据是否需要过滤 IgnoreExcelAttribute 进行筛选
|
// 获取目标类型的所有属性,并根据是否需要过滤 IgnoreExcelAttribute 进行筛选
|
||||||
@@ -451,7 +457,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
importPreviewOutput.Data = channels.ToDictionary(a => a.Name);
|
importPreviewOutput.Data = channels.DistinctBy(a => a.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion sheet
|
#endregion sheet
|
||||||
|
|||||||
@@ -133,7 +133,6 @@ public static class ChannelServiceHelpers
|
|||||||
//导入检验结果
|
//导入检验结果
|
||||||
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
||||||
//设备页
|
//设备页
|
||||||
ImportPreviewOutput<Channel> channelImportPreview = new();
|
|
||||||
|
|
||||||
var sheetNames = uSheetDatas.sheets.Keys.ToList();
|
var sheetNames = uSheetDatas.sheets.Keys.ToList();
|
||||||
foreach (var sheetName in sheetNames)
|
foreach (var sheetName in sheetNames)
|
||||||
@@ -156,10 +155,11 @@ public static class ChannelServiceHelpers
|
|||||||
rows.Add(expando);
|
rows.Add(expando);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalData.ChannelService.SetChannelData(dataScope, channelDicts, ImportPreviews, channelImportPreview, sheetName, rows);
|
GlobalData.ChannelService.SetChannelData(dataScope, channelDicts, ImportPreviews, sheetName, rows);
|
||||||
if (channelImportPreview.HasError)
|
var data = ImportPreviews?.FirstOrDefault().Value;
|
||||||
|
if (data?.HasError == true)
|
||||||
{
|
{
|
||||||
throw new(channelImportPreview.Results.FirstOrDefault(a => !a.Success).ErrorMessage ?? "error");
|
throw new(data.Results.FirstOrDefault(a => !a.Success).ErrorMessage ?? "error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ internal interface IChannelService
|
|||||||
Task<bool> BatchSaveAsync(List<Channel> input, ItemChangedType type);
|
Task<bool> BatchSaveAsync(List<Channel> input, ItemChangedType type);
|
||||||
|
|
||||||
|
|
||||||
void SetChannelData(HashSet<long>? dataScope, Dictionary<string, Channel> channelDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, ImportPreviewOutput<Channel> channelImportPreview, string sheetName, IEnumerable<IDictionary<string, object>> rows);
|
void SetChannelData(HashSet<long>? dataScope, Dictionary<string, Channel> channelDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, string sheetName, IEnumerable<IDictionary<string, object>> rows);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存是否输出日志和日志等级
|
/// 保存是否输出日志和日志等级
|
||||||
|
|||||||
@@ -337,8 +337,8 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
|||||||
{
|
{
|
||||||
channelDicts.TryGetValue(a, out var channel);
|
channelDicts.TryGetValue(a, out var channel);
|
||||||
var pluginKey = channel?.PluginName;
|
var pluginKey = channel?.PluginName;
|
||||||
return (a, pluginKey);
|
return pluginKey;
|
||||||
}).ToList();
|
}).ToHashSet();
|
||||||
|
|
||||||
var sheets = DeviceServiceHelpers.ExportSheets(devices, plugins, deviceDicts, channelDicts, pluginSheetNames); // IEnumerable 延迟执行
|
var sheets = DeviceServiceHelpers.ExportSheets(devices, plugins, deviceDicts, channelDicts, pluginSheetNames); // IEnumerable 延迟执行
|
||||||
|
|
||||||
@@ -362,18 +362,18 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
|||||||
/// 导出文件
|
/// 导出文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[OperDesc("ExportDevice", isRecordPar: false, localizerType: typeof(Device))]
|
[OperDesc("ExportDevice", isRecordPar: false, localizerType: typeof(Device))]
|
||||||
public async Task<MemoryStream> ExportMemoryStream(List<Device>? data, string channelName = null, string plugin = null)
|
public async Task<MemoryStream> ExportMemoryStream(List<Device>? models, string channelName = null, string plugin = null)
|
||||||
{
|
{
|
||||||
var deviceDicts = (await GlobalData.DeviceService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
var deviceDicts = (await GlobalData.DeviceService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
var channelDicts = (await GlobalData.ChannelService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
var channelDicts = (await GlobalData.ChannelService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
var pluginSheetNames = data.Select(a => a.ChannelId).Select(a =>
|
var pluginSheetNames = models.Select(a => a.ChannelId).Select(a =>
|
||||||
{
|
{
|
||||||
channelDicts.TryGetValue(a, out var channel);
|
channelDicts.TryGetValue(a, out var channel);
|
||||||
var pluginKey = channel?.PluginName ?? plugin;
|
var pluginKey = channel?.PluginName;
|
||||||
return (a, pluginKey);
|
return pluginKey;
|
||||||
}).ToList();
|
}).ToHashSet();
|
||||||
|
|
||||||
var sheets = DeviceServiceHelpers.ExportSheets(data, deviceDicts, channelDicts, pluginSheetNames, channelName);
|
var sheets = DeviceServiceHelpers.ExportSheets(models, deviceDicts, channelDicts, pluginSheetNames, channelName);
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
await memoryStream.SaveAsAsync(sheets).ConfigureAwait(false);
|
await memoryStream.SaveAsAsync(sheets).ConfigureAwait(false);
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
@@ -407,8 +407,16 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
|||||||
ManageHelper.CheckDeviceCount(insertData.Count);
|
ManageHelper.CheckDeviceCount(insertData.Count);
|
||||||
|
|
||||||
using var db = GetDB();
|
using var db = GetDB();
|
||||||
await db.BulkCopyAsync(insertData, 100000).ConfigureAwait(false);
|
if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory > 2 * 1024 * 1024)
|
||||||
await db.BulkUpdateAsync(upData, 100000).ConfigureAwait(false);
|
{
|
||||||
|
await db.BulkCopyAsync(insertData, 200000).ConfigureAwait(false);
|
||||||
|
await db.BulkUpdateAsync(upData, 200000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await db.BulkCopyAsync(insertData, 10000).ConfigureAwait(false);
|
||||||
|
await db.BulkUpdateAsync(upData, 10000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
DeleteDeviceFromCache();
|
DeleteDeviceFromCache();
|
||||||
return devices.Select(a => a.Id).ToHashSet();
|
return devices.Select(a => a.Id).ToHashSet();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ public static class DeviceServiceHelpers
|
|||||||
{
|
{
|
||||||
channelDicts.TryGetValue(a, out var channel);
|
channelDicts.TryGetValue(a, out var channel);
|
||||||
var pluginKey = channel?.PluginName;
|
var pluginKey = channel?.PluginName;
|
||||||
return (a, pluginKey);
|
return pluginKey;
|
||||||
}).ToList();
|
}).ToHashSet();
|
||||||
var data = ExportSheets(models, deviceDicts, channelDicts, pluginSheetNames); // IEnumerable 延迟执行
|
var data = ExportSheets(models, deviceDicts, channelDicts, pluginSheetNames); // IEnumerable 延迟执行
|
||||||
return USheetDataHelpers.GetUSheetDatas(data);
|
return USheetDataHelpers.GetUSheetDatas(data);
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public static class DeviceServiceHelpers
|
|||||||
IEnumerable<Device>? data,
|
IEnumerable<Device>? data,
|
||||||
Dictionary<long, Device>? deviceDicts,
|
Dictionary<long, Device>? deviceDicts,
|
||||||
Dictionary<long, Channel> channelDicts,
|
Dictionary<long, Channel> channelDicts,
|
||||||
IEnumerable<(long, string)>? pluginSheetNames,
|
HashSet<string> pluginSheetNames,
|
||||||
string? channelName = null)
|
string? channelName = null)
|
||||||
{
|
{
|
||||||
if (data?.Any() != true)
|
if (data?.Any() != true)
|
||||||
@@ -51,14 +51,13 @@ IEnumerable<(long, string)>? pluginSheetNames,
|
|||||||
ConcurrentDictionary<string, (object, Dictionary<string, PropertyInfo>)> propertysDict = new();
|
ConcurrentDictionary<string, (object, Dictionary<string, PropertyInfo>)> propertysDict = new();
|
||||||
|
|
||||||
|
|
||||||
foreach (var dName in pluginSheetNames.DistinctBy(a => a.Item2))
|
foreach (var plugin in pluginSheetNames)
|
||||||
{
|
{
|
||||||
var filtResult = PluginServiceUtil.GetFileNameAndTypeName(dName.Item2);
|
var filtered = FilterPluginDevices(data, plugin, channelDicts);
|
||||||
var ids = pluginSheetNames.Where(a => a.Item2 == dName.Item2).Select(a => a.Item1).ToHashSet();
|
var filtResult = PluginServiceUtil.GetFileNameAndTypeName(plugin);
|
||||||
var pluginSheets = GetPluginSheets(data.Where(a => ids.Contains(a.ChannelId)), propertysDict, dName.Item2);
|
var pluginSheets = GetPluginSheets(filtered, propertysDict, plugin);
|
||||||
result.Add(filtResult.TypeName, pluginSheets);
|
result.Add(filtResult.TypeName, pluginSheets);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +67,7 @@ IAsyncEnumerable<Device>? data1,
|
|||||||
IAsyncEnumerable<Device>? data2,
|
IAsyncEnumerable<Device>? data2,
|
||||||
Dictionary<long, Device>? deviceDicts,
|
Dictionary<long, Device>? deviceDicts,
|
||||||
Dictionary<long, Channel> channelDicts,
|
Dictionary<long, Channel> channelDicts,
|
||||||
IEnumerable<(long, string)>? pluginSheetNames,
|
HashSet<string> pluginSheetNames,
|
||||||
string? channelName = null)
|
string? channelName = null)
|
||||||
{
|
{
|
||||||
if (data1 == null || data2 == null)
|
if (data1 == null || data2 == null)
|
||||||
@@ -78,19 +77,51 @@ string? channelName = null)
|
|||||||
result.Add(ExportString.DeviceName, GetDeviceSheets(data1, deviceDicts, channelDicts, channelName));
|
result.Add(ExportString.DeviceName, GetDeviceSheets(data1, deviceDicts, channelDicts, channelName));
|
||||||
ConcurrentDictionary<string, (object, Dictionary<string, PropertyInfo>)> propertysDict = new();
|
ConcurrentDictionary<string, (object, Dictionary<string, PropertyInfo>)> propertysDict = new();
|
||||||
|
|
||||||
foreach (var dName in pluginSheetNames.DistinctBy(a => a.Item2))
|
|
||||||
|
foreach (var plugin in pluginSheetNames)
|
||||||
{
|
{
|
||||||
var filtResult = PluginServiceUtil.GetFileNameAndTypeName(dName.Item2);
|
var filtered = FilterPluginDevices(data2, plugin, channelDicts);
|
||||||
var ids = pluginSheetNames.Where(a => a.Item2 == dName.Item2).Select(a => a.Item1).ToHashSet();
|
var filtResult = PluginServiceUtil.GetFileNameAndTypeName(plugin);
|
||||||
var pluginSheets = GetPluginSheets(data2.Where(a => ids.Contains(a.ChannelId)), propertysDict, dName.Item2);
|
var pluginSheets = GetPluginSheets(filtered, propertysDict, plugin);
|
||||||
result.Add(filtResult.TypeName, pluginSheets);
|
result.Add(filtResult.TypeName, pluginSheets);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
static IAsyncEnumerable<Device> FilterPluginDevices(IAsyncEnumerable<Device> data, string plugin, Dictionary<long, Channel> channelDicts)
|
||||||
|
{
|
||||||
|
return data.Where(device =>
|
||||||
|
{
|
||||||
|
if (channelDicts.TryGetValue(device.ChannelId, out var channel))
|
||||||
|
{
|
||||||
|
if (channel.PluginName == plugin)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static IEnumerable<Device> FilterPluginDevices(IEnumerable<Device> data, string plugin, Dictionary<long, Channel> channelDicts)
|
||||||
|
{
|
||||||
|
return data.Where(device =>
|
||||||
|
{
|
||||||
|
if (channelDicts.TryGetValue(device.ChannelId, out var channel))
|
||||||
|
{
|
||||||
|
if (channel.PluginName == plugin)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static IEnumerable<Dictionary<string, object>> GetDeviceSheets(
|
static IEnumerable<Dictionary<string, object>> GetDeviceSheets(
|
||||||
IEnumerable<Device> data,
|
IEnumerable<Device> data,
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ internal sealed class GatewayMonitorHostedService : BackgroundService, IGatewayM
|
|||||||
//网关启动时,获取所有通道
|
//网关启动时,获取所有通道
|
||||||
var channelRuntimes = (await GlobalData.ChannelService.GetAllAsync().ConfigureAwait(false)).AdaptListChannelRuntime();
|
var channelRuntimes = (await GlobalData.ChannelService.GetAllAsync().ConfigureAwait(false)).AdaptListChannelRuntime();
|
||||||
var deviceRuntimes = (await GlobalData.DeviceService.GetAllAsync().ConfigureAwait(false)).AdaptListDeviceRuntime();
|
var deviceRuntimes = (await GlobalData.DeviceService.GetAllAsync().ConfigureAwait(false)).AdaptListDeviceRuntime();
|
||||||
var variableRuntimes = (await GlobalData.VariableService.GetAllAsync().ConfigureAwait(false)).AdaptListVariableRuntime();
|
|
||||||
|
var variableRuntimes = GlobalData.VariableService.GetAllVariableRuntime();
|
||||||
|
|
||||||
foreach (var channelRuntime in channelRuntimes)
|
foreach (var channelRuntime in channelRuntimes)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ namespace ThingsGateway.Gateway.Application
|
|||||||
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile);
|
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile);
|
||||||
|
|
||||||
Task<bool> SaveVariableAsync(Variable input, ItemChangedType type, bool restart, CancellationToken cancellationToken);
|
Task<bool> SaveVariableAsync(Variable input, ItemChangedType type, bool restart, CancellationToken cancellationToken);
|
||||||
void PreheatCache();
|
|
||||||
|
|
||||||
Task<MemoryStream> ExportMemoryStream(List<Variable> data, string devName);
|
Task<MemoryStream> ExportMemoryStream(List<Variable> data, string devName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,8 +88,6 @@ internal interface IVariableService
|
|||||||
/// <param name="exportFilter">查询分页选项</param>
|
/// <param name="exportFilter">查询分页选项</param>
|
||||||
Task<QueryData<Variable>> PageAsync(ExportFilter exportFilter);
|
Task<QueryData<Variable>> PageAsync(ExportFilter exportFilter);
|
||||||
|
|
||||||
Task PreheatCache();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步预览导入的数据。
|
/// 异步预览导入的数据。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -113,5 +111,6 @@ internal interface IVariableService
|
|||||||
|
|
||||||
Task<List<Variable>> GetByDeviceIdAsync(List<long> deviceIds);
|
Task<List<Variable>> GetByDeviceIdAsync(List<long> deviceIds);
|
||||||
void DeleteVariableCache();
|
void DeleteVariableCache();
|
||||||
Task<ImportPreviewOutput<Dictionary<string, Variable>>> SetVariableData(HashSet<long>? dataScope, Dictionary<string, Device> deviceDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, ImportPreviewOutput<Dictionary<string, Variable>> deviceImportPreview, Dictionary<string, PluginInfo> driverPluginNameDict, ConcurrentDictionary<string, (Type, Dictionary<string, PropertyInfo>, Dictionary<string, PropertyInfo>)> propertysDict, string sheetName, IEnumerable<IDictionary<string, object>> rows);
|
ImportPreviewOutput<Dictionary<string, Variable>> SetVariableData(HashSet<long>? dataScope, Dictionary<string, Device> deviceDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, ImportPreviewOutput<Dictionary<string, Variable>> deviceImportPreview, Dictionary<string, PluginInfo> driverPluginNameDict, ConcurrentDictionary<string, (Type, Dictionary<string, PropertyInfo>, Dictionary<string, PropertyInfo>)> propertysDict, string sheetName, IEnumerable<IDictionary<string, object>> rows);
|
||||||
|
List<VariableRuntime> GetAllVariableRuntime();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,8 +286,6 @@ public class VariableRuntimeService : IVariableRuntimeService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PreheatCache() => GlobalData.VariableService.PreheatCache();
|
|
||||||
|
|
||||||
|
|
||||||
public Task<MemoryStream> ExportMemoryStream(List<Variable> data, string deviceName) => GlobalData.VariableService.ExportMemoryStream(data, deviceName);
|
public Task<MemoryStream> ExportMemoryStream(List<Variable> data, string deviceName) => GlobalData.VariableService.ExportMemoryStream(data, deviceName);
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ using System.Text;
|
|||||||
|
|
||||||
using ThingsGateway.Extension.Generic;
|
using ThingsGateway.Extension.Generic;
|
||||||
using ThingsGateway.Foundation.Extension.Dynamic;
|
using ThingsGateway.Foundation.Extension.Dynamic;
|
||||||
using ThingsGateway.NewLife;
|
|
||||||
using ThingsGateway.SqlSugar;
|
using ThingsGateway.SqlSugar;
|
||||||
|
|
||||||
using TouchSocket.Core;
|
using TouchSocket.Core;
|
||||||
@@ -212,9 +211,19 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
|
|
||||||
var result = await db.UseTranAsync(async () =>
|
var result = await db.UseTranAsync(async () =>
|
||||||
{
|
{
|
||||||
await db.BulkCopyAsync(newChannels, 100000).ConfigureAwait(false);
|
if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory > 2 * 1024 * 1024)
|
||||||
await db.BulkCopyAsync(newDevices, 100000).ConfigureAwait(false);
|
{
|
||||||
await db.BulkCopyAsync(newVariables, 100000).ConfigureAwait(false);
|
await db.BulkCopyAsync(newChannels, 200000).ConfigureAwait(false);
|
||||||
|
await db.BulkCopyAsync(newDevices, 200000).ConfigureAwait(false);
|
||||||
|
await db.BulkCopyAsync(newVariables, 200000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await db.BulkCopyAsync(newChannels, 10000).ConfigureAwait(false);
|
||||||
|
await db.BulkCopyAsync(newDevices, 10000).ConfigureAwait(false);
|
||||||
|
await db.BulkCopyAsync(newVariables, 10000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
if (result.IsSuccess)//如果成功了
|
if (result.IsSuccess)//如果成功了
|
||||||
{
|
{
|
||||||
@@ -372,6 +381,12 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="exportFilter">查询条件</param>
|
/// <param name="exportFilter">查询条件</param>
|
||||||
public async Task<QueryData<Variable>> PageAsync(ExportFilter exportFilter)
|
public async Task<QueryData<Variable>> PageAsync(ExportFilter exportFilter)
|
||||||
|
{
|
||||||
|
var whereQuery = await GetWhereQueryFunc(exportFilter).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return await QueryAsync(exportFilter.QueryPageOptions, whereQuery).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
private async Task<Func<ISugarQueryable<Variable>, ISugarQueryable<Variable>>> GetWhereQueryFunc(ExportFilter exportFilter)
|
||||||
{
|
{
|
||||||
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
||||||
HashSet<long>? deviceId = null;
|
HashSet<long>? deviceId = null;
|
||||||
@@ -384,7 +399,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
{
|
{
|
||||||
deviceId = (await _deviceService.GetAllAsync().ConfigureAwait(false)).Where(a => a.ChannelId == exportFilter.ChannelId).Select(a => a.Id).ToHashSet();
|
deviceId = (await _deviceService.GetAllAsync().ConfigureAwait(false)).Where(a => a.ChannelId == exportFilter.ChannelId).Select(a => a.Id).ToHashSet();
|
||||||
}
|
}
|
||||||
return await QueryAsync(exportFilter.QueryPageOptions, a => a
|
var whereQuery = (ISugarQueryable<Variable> a) => a
|
||||||
.WhereIF(!exportFilter.QueryPageOptions.SearchText.IsNullOrWhiteSpace(), a => a.Name.Contains(exportFilter.QueryPageOptions.SearchText!))
|
.WhereIF(!exportFilter.QueryPageOptions.SearchText.IsNullOrWhiteSpace(), a => a.Name.Contains(exportFilter.QueryPageOptions.SearchText!))
|
||||||
.WhereIF(exportFilter.PluginType == PluginTypeEnum.Collect, a => a.DeviceId == exportFilter.DeviceId)
|
.WhereIF(exportFilter.PluginType == PluginTypeEnum.Collect, a => a.DeviceId == exportFilter.DeviceId)
|
||||||
.WhereIF(deviceId != null, a => deviceId.Contains(a.DeviceId))
|
.WhereIF(deviceId != null, a => deviceId.Contains(a.DeviceId))
|
||||||
@@ -393,9 +408,34 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
||||||
|
|
||||||
|
|
||||||
.WhereIF(exportFilter.PluginType == PluginTypeEnum.Business, u => SqlFunc.JsonLike(u.VariablePropertys, exportFilter.DeviceId.ToString()))
|
.WhereIF(exportFilter.PluginType == PluginTypeEnum.Business, u => SqlFunc.JsonLike(u.VariablePropertys, exportFilter.DeviceId.ToString()));
|
||||||
|
return whereQuery;
|
||||||
|
}
|
||||||
|
|
||||||
).ConfigureAwait(false);
|
private async Task<Func<IEnumerable<Variable>, IEnumerable<Variable>>> GetWhereEnumerableFunc(ExportFilter exportFilter)
|
||||||
|
{
|
||||||
|
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
||||||
|
HashSet<long>? deviceId = null;
|
||||||
|
if (!exportFilter.PluginName.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
var channel = (await _channelService.GetAllAsync().ConfigureAwait(false)).Where(a => a.PluginName == exportFilter.PluginName).Select(a => a.Id).ToHashSet();
|
||||||
|
deviceId = (await _deviceService.GetAllAsync().ConfigureAwait(false)).Where(a => channel.Contains(a.ChannelId)).Select(a => a.Id).ToHashSet();
|
||||||
|
}
|
||||||
|
else if (exportFilter.ChannelId != null)
|
||||||
|
{
|
||||||
|
deviceId = (await _deviceService.GetAllAsync().ConfigureAwait(false)).Where(a => a.ChannelId == exportFilter.ChannelId).Select(a => a.Id).ToHashSet();
|
||||||
|
}
|
||||||
|
var whereQuery = (IEnumerable<Variable> a) => a
|
||||||
|
.WhereIF(!exportFilter.QueryPageOptions.SearchText.IsNullOrWhiteSpace(), a => a.Name.Contains(exportFilter.QueryPageOptions.SearchText!))
|
||||||
|
.WhereIF(exportFilter.PluginType == PluginTypeEnum.Collect, a => a.DeviceId == exportFilter.DeviceId)
|
||||||
|
.WhereIF(deviceId != null, a => deviceId.Contains(a.DeviceId))
|
||||||
|
|
||||||
|
.WhereIF(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.CreateOrgId))//在指定机构列表查询
|
||||||
|
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
||||||
|
|
||||||
|
|
||||||
|
.WhereIF(exportFilter.PluginType == PluginTypeEnum.Business, u => SqlFunc.JsonLike(u.VariablePropertys, exportFilter.DeviceId.ToString()));
|
||||||
|
return whereQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -424,15 +464,36 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
App.CacheService.Remove(ThingsGatewayCacheConst.Cache_Variable);
|
App.CacheService.Remove(ThingsGatewayCacheConst.Cache_Variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<VariableRuntime> GetAllVariableRuntime()
|
||||||
|
{
|
||||||
|
using (var db = DbContext.GetDB<Variable>())
|
||||||
|
{
|
||||||
|
var deviceVariables = db.Queryable<Variable>().OrderBy(a => a.Id).GetEnumerable();
|
||||||
|
return deviceVariables.AdaptListVariableRuntime();
|
||||||
|
}
|
||||||
|
}
|
||||||
#region 导出
|
#region 导出
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 导出文件
|
/// 导出文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[OperDesc("ExportVariable", isRecordPar: false, localizerType: typeof(Variable))]
|
[OperDesc("ExportVariable", isRecordPar: false, localizerType: typeof(Variable))]
|
||||||
public async Task<MemoryStream> ExportMemoryStream(List<Variable> data, string deviceName = null)
|
public async Task<MemoryStream> ExportMemoryStream(List<Variable> variables, string deviceName = null)
|
||||||
{
|
{
|
||||||
var sheets = await VariableServiceHelpers.ExportCoreAsync(data, deviceName).ConfigureAwait(false);
|
var deviceDicts = (await GlobalData.DeviceService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
|
var channelDicts = (await GlobalData.ChannelService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
|
var pluginSheetNames = variables.Where(a => a.VariablePropertys?.Count > 0).SelectMany(a => a.VariablePropertys).Select(a =>
|
||||||
|
{
|
||||||
|
if (deviceDicts.TryGetValue(a.Key, out var device) && channelDicts.TryGetValue(device.ChannelId, out var channel))
|
||||||
|
{
|
||||||
|
var pluginKey = channel?.PluginName;
|
||||||
|
using var businessBase = (BusinessBase)GlobalData.PluginService.GetDriver(pluginKey);
|
||||||
|
return new KeyValuePair<string, VariablePropertyBase>(pluginKey, businessBase.VariablePropertys);
|
||||||
|
}
|
||||||
|
return new KeyValuePair<string, VariablePropertyBase>(string.Empty, null);
|
||||||
|
}).Where(a => a.Value != null).DistinctBy(a => a.Key).ToDictionary();
|
||||||
|
var sheets = VariableServiceHelpers.ExportSheets(variables, deviceDicts, channelDicts, pluginSheetNames); // IEnumerable 延迟执行
|
||||||
|
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
await memoryStream.SaveAsAsync(sheets).ConfigureAwait(false);
|
await memoryStream.SaveAsAsync(sheets).ConfigureAwait(false);
|
||||||
@@ -446,11 +507,52 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
[OperDesc("ExportVariable", isRecordPar: false, localizerType: typeof(Variable))]
|
[OperDesc("ExportVariable", isRecordPar: false, localizerType: typeof(Variable))]
|
||||||
public async Task<Dictionary<string, object>> ExportVariableAsync(ExportFilter exportFilter)
|
public async Task<Dictionary<string, object>> ExportVariableAsync(ExportFilter exportFilter)
|
||||||
{
|
{
|
||||||
var data = (await PageAsync(exportFilter).ConfigureAwait(false));
|
if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory < 4 * 1024 * 1024)
|
||||||
var sheets = await VariableServiceHelpers.ExportCoreAsync(data.Items, sortName: exportFilter.QueryPageOptions.SortName, sortOrder: exportFilter.QueryPageOptions.SortOrder).ConfigureAwait(false);
|
{
|
||||||
return sheets;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var whereQuery = await GetWhereEnumerableFunc(exportFilter).ConfigureAwait(false);
|
||||||
|
//导出
|
||||||
|
var variables = GlobalData.IdVariables.Select(a => a.Value).GetQuery(exportFilter.QueryPageOptions, whereQuery, exportFilter.FilterKeyValueAction);
|
||||||
|
|
||||||
|
var deviceDicts = (await GlobalData.DeviceService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
|
var channelDicts = (await GlobalData.ChannelService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
|
var pluginSheetNames = variables.Where(a => a.VariablePropertys?.Count > 0).SelectMany(a => a.VariablePropertys).Select(a =>
|
||||||
|
{
|
||||||
|
if (deviceDicts.TryGetValue(a.Key, out var device) && channelDicts.TryGetValue(device.ChannelId, out var channel))
|
||||||
|
{
|
||||||
|
var pluginKey = channel?.PluginName;
|
||||||
|
using var businessBase = (BusinessBase)GlobalData.PluginService.GetDriver(pluginKey);
|
||||||
|
return new KeyValuePair<string, VariablePropertyBase>(pluginKey, businessBase.VariablePropertys);
|
||||||
|
}
|
||||||
|
return new KeyValuePair<string, VariablePropertyBase>(string.Empty, null);
|
||||||
|
}).Where(a => a.Value != null).DistinctBy(a => a.Key).ToDictionary();
|
||||||
|
|
||||||
|
var sheets = VariableServiceHelpers.ExportSheets(variables, deviceDicts, channelDicts, pluginSheetNames); // IEnumerable 延迟执行
|
||||||
|
|
||||||
|
return sheets;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var data = (await PageAsync(exportFilter).ConfigureAwait(false));
|
||||||
|
var sheets = await VariableServiceHelpers.ExportCoreAsync(data.Items, sortName: exportFilter.QueryPageOptions.SortName, sortOrder: exportFilter.QueryPageOptions.SortOrder).ConfigureAwait(false);
|
||||||
|
return sheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private async Task<IAsyncEnumerable<Variable>> GetAsyncEnumerableData(ExportFilter exportFilter)
|
||||||
|
{
|
||||||
|
var whereQuery = await GetEnumerableData(exportFilter).ConfigureAwait(false);
|
||||||
|
return whereQuery.GetAsyncEnumerable();
|
||||||
|
}
|
||||||
|
private async Task<ISugarQueryable<Variable>> GetEnumerableData(ExportFilter exportFilter)
|
||||||
|
{
|
||||||
|
var db = GetDB();
|
||||||
|
var whereQuery = await GetWhereQueryFunc(exportFilter).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return GetQuery(db, exportFilter.QueryPageOptions, whereQuery, exportFilter.FilterKeyValueAction);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion 导出
|
#endregion 导出
|
||||||
@@ -475,53 +577,21 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
var insertData = variables.Where(a => !a.IsUp).ToList();
|
var insertData = variables.Where(a => !a.IsUp).ToList();
|
||||||
ManageHelper.CheckVariableCount(insertData.Count);
|
ManageHelper.CheckVariableCount(insertData.Count);
|
||||||
using var db = GetDB();
|
using var db = GetDB();
|
||||||
await db.BulkCopyAsync(insertData, 100000).ConfigureAwait(false);
|
if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory > 2 * 1024 * 1024)
|
||||||
await db.BulkUpdateAsync(upData, 100000).ConfigureAwait(false);
|
{
|
||||||
|
await db.BulkCopyAsync(insertData, 200000).ConfigureAwait(false);
|
||||||
|
await db.BulkUpdateAsync(upData, 200000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await db.BulkCopyAsync(insertData, 10000).ConfigureAwait(false);
|
||||||
|
await db.BulkUpdateAsync(upData, 10000).ConfigureAwait(false);
|
||||||
|
}
|
||||||
DeleteVariableCache();
|
DeleteVariableCache();
|
||||||
return variables.Select(a => a.Id).ToHashSet();
|
return variables.Select(a => a.Id).ToHashSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly WaitLock _cacheLock = new();
|
|
||||||
|
|
||||||
private async Task<Dictionary<long, Dictionary<string, DeviecIdVariableImportData>>> GetVariableImportData()
|
|
||||||
{
|
|
||||||
var key = ThingsGatewayCacheConst.Cache_Variable;
|
|
||||||
var datas = App.CacheService.Get<Dictionary<long, Dictionary<string, DeviecIdVariableImportData>>>(key);
|
|
||||||
|
|
||||||
if (datas == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await _cacheLock.WaitAsync().ConfigureAwait(false);
|
|
||||||
datas = App.CacheService.Get<Dictionary<long, Dictionary<string, DeviecIdVariableImportData>>>(key);
|
|
||||||
if (datas == null)
|
|
||||||
{
|
|
||||||
using var db = GetDB();
|
|
||||||
datas = (await db.Queryable<Variable>().Select<DeviecIdVariableImportData>().ToListAsync().ConfigureAwait(false)).GroupBy(a => a.DeviceId).ToDictionary(a => a.Key, a => a.ToDictionary(a => a.Name));
|
|
||||||
|
|
||||||
App.CacheService.Set(key, datas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_cacheLock.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return datas;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task PreheatCache()
|
|
||||||
{
|
|
||||||
return GetVariableImportData();
|
|
||||||
}
|
|
||||||
private sealed class DeviecIdVariableImportData
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
public long DeviceId { get; set; }
|
|
||||||
public long CreateOrgId { get; set; }
|
|
||||||
public long CreateUserId { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile)
|
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile)
|
||||||
{
|
{
|
||||||
@@ -552,7 +622,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
// 获取当前工作表的所有行数据
|
// 获取当前工作表的所有行数据
|
||||||
var rows = MiniExcel.Query(path, useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
|
var rows = MiniExcel.Query(path, useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
|
||||||
|
|
||||||
deviceImportPreview = await SetVariableData(dataScope, deviceDicts, ImportPreviews, deviceImportPreview, driverPluginNameDict, propertysDict, sheetName, rows).ConfigureAwait(false);
|
deviceImportPreview = SetVariableData(dataScope, deviceDicts, ImportPreviews, deviceImportPreview, driverPluginNameDict, propertysDict, sheetName, rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImportPreviews;
|
return ImportPreviews;
|
||||||
@@ -564,7 +634,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ImportPreviewOutput<Dictionary<string, Variable>>> SetVariableData(HashSet<long>? dataScope, Dictionary<string, Device> deviceDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, ImportPreviewOutput<Dictionary<string, Variable>> deviceImportPreview, Dictionary<string, PluginInfo> driverPluginNameDict, ConcurrentDictionary<string, (Type, Dictionary<string, PropertyInfo>, Dictionary<string, PropertyInfo>)> propertysDict, string sheetName, IEnumerable<IDictionary<string, object>> rows)
|
public ImportPreviewOutput<Dictionary<string, Variable>> SetVariableData(HashSet<long>? dataScope, Dictionary<string, Device> deviceDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, ImportPreviewOutput<Dictionary<string, Variable>> deviceImportPreview, Dictionary<string, PluginInfo> driverPluginNameDict, ConcurrentDictionary<string, (Type, Dictionary<string, PropertyInfo>, Dictionary<string, PropertyInfo>)> propertysDict, string sheetName, IEnumerable<IDictionary<string, object>> rows)
|
||||||
{
|
{
|
||||||
// 变量页处理
|
// 变量页处理
|
||||||
if (sheetName == ExportString.VariableName)
|
if (sheetName == ExportString.VariableName)
|
||||||
@@ -581,8 +651,6 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
var variableProperties = type.GetRuntimeProperties().Where(a => (a.GetCustomAttribute<IgnoreExcelAttribute>() == null) && a.CanWrite)
|
var variableProperties = type.GetRuntimeProperties().Where(a => (a.GetCustomAttribute<IgnoreExcelAttribute>() == null) && a.CanWrite)
|
||||||
.ToDictionary(a => type.GetPropertyDisplayName(a.Name), a => (a, a.IsNullableType()));
|
.ToDictionary(a => type.GetPropertyDisplayName(a.Name), a => (a, a.IsNullableType()));
|
||||||
|
|
||||||
var dbVariableDicts = await GetVariableImportData().ConfigureAwait(false);
|
|
||||||
|
|
||||||
// 并行处理每一行数据
|
// 并行处理每一行数据
|
||||||
rows.ParallelForEachStreamed((item, state, index) =>
|
rows.ParallelForEachStreamed((item, state, index) =>
|
||||||
{
|
{
|
||||||
@@ -629,7 +697,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbVariableDicts.TryGetValue(variable.DeviceId, out var dbvar1s) && dbvar1s.TryGetValue(variable.Name, out var dbvar1))
|
if (GlobalData.IdDevices.TryGetValue(variable.DeviceId, out var dbvar1s) && dbvar1s.VariableRuntimes.TryGetValue(variable.Name, out var dbvar1))
|
||||||
{
|
{
|
||||||
variable.Id = dbvar1.Id;
|
variable.Id = dbvar1.Id;
|
||||||
variable.CreateOrgId = dbvar1.CreateOrgId;
|
variable.CreateOrgId = dbvar1.CreateOrgId;
|
||||||
|
|||||||
@@ -21,12 +21,295 @@ namespace ThingsGateway.Gateway.Application;
|
|||||||
public static class VariableServiceHelpers
|
public static class VariableServiceHelpers
|
||||||
{
|
{
|
||||||
|
|
||||||
public static async Task<USheetDatas> ExportVariableAsync(IEnumerable<Variable> models, string sortName = nameof(Variable.Id), SortOrder sortOrder = SortOrder.Asc)
|
public static async Task<USheetDatas> ExportVariableAsync(IEnumerable<Variable> variables, string sortName = nameof(Variable.Id), SortOrder sortOrder = SortOrder.Asc)
|
||||||
{
|
{
|
||||||
var data = await ExportCoreAsync(models, sortName: sortName, sortOrder: sortOrder).ConfigureAwait(false);
|
var deviceDicts = (await GlobalData.DeviceService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
|
var channelDicts = (await GlobalData.ChannelService.GetAllAsync().ConfigureAwait(false)).ToDictionary(a => a.Id);
|
||||||
|
var pluginSheetNames = variables.Where(a => a.VariablePropertys?.Count > 0).SelectMany(a => a.VariablePropertys).Select(a =>
|
||||||
|
{
|
||||||
|
if (deviceDicts.TryGetValue(a.Key, out var device) && channelDicts.TryGetValue(device.ChannelId, out var channel))
|
||||||
|
{
|
||||||
|
var pluginKey = channel?.PluginName;
|
||||||
|
using var businessBase = (BusinessBase)GlobalData.PluginService.GetDriver(pluginKey);
|
||||||
|
return new KeyValuePair<string, VariablePropertyBase>(pluginKey, businessBase.VariablePropertys);
|
||||||
|
}
|
||||||
|
return new KeyValuePair<string, VariablePropertyBase>(string.Empty, null);
|
||||||
|
}).Where(a => a.Value != null).DistinctBy(a => a.Key).ToDictionary();
|
||||||
|
var data = ExportSheets(variables, deviceDicts, channelDicts, pluginSheetNames); // IEnumerable 延迟执行
|
||||||
return USheetDataHelpers.GetUSheetDatas(data);
|
return USheetDataHelpers.GetUSheetDatas(data);
|
||||||
}
|
}
|
||||||
|
static IAsyncEnumerable<Variable> FilterPluginDevices(
|
||||||
|
IAsyncEnumerable<Variable> data,
|
||||||
|
string pluginName,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
Dictionary<long, Channel> channelDicts)
|
||||||
|
{
|
||||||
|
return data.Where(variable =>
|
||||||
|
{
|
||||||
|
if (variable.VariablePropertys == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var a in variable.VariablePropertys)
|
||||||
|
{
|
||||||
|
if (deviceDicts.TryGetValue(a.Key, out var device) && channelDicts.TryGetValue(device.ChannelId, out var channel))
|
||||||
|
|
||||||
|
{
|
||||||
|
if (channel.PluginName == pluginName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static IEnumerable<Variable> FilterPluginDevices(
|
||||||
|
IEnumerable<Variable> data,
|
||||||
|
string pluginName,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
Dictionary<long, Channel> channelDicts)
|
||||||
|
{
|
||||||
|
return data.Where(variable =>
|
||||||
|
{
|
||||||
|
if (variable.VariablePropertys == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var a in variable.VariablePropertys)
|
||||||
|
{
|
||||||
|
if (deviceDicts.TryGetValue(a.Key, out var device) && channelDicts.TryGetValue(device.ChannelId, out var channel))
|
||||||
|
{
|
||||||
|
if (channel.PluginName == pluginName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Dictionary<string, object> ExportSheets(
|
||||||
|
IEnumerable<Variable> data,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
Dictionary<long, Channel> channelDicts,
|
||||||
|
Dictionary<string, VariablePropertyBase> pluginDrivers,
|
||||||
|
string? deviceName = null)
|
||||||
|
{
|
||||||
|
var sheets = new Dictionary<string, object>();
|
||||||
|
var propertysDict = new ConcurrentDictionary<string, (VariablePropertyBase, Dictionary<string, PropertyInfo>)>();
|
||||||
|
|
||||||
|
// 主变量页
|
||||||
|
sheets.Add(ExportString.VariableName, GetVariableSheets(data, deviceDicts, deviceName));
|
||||||
|
|
||||||
|
// 插件页(动态推导)
|
||||||
|
foreach (var plugin in pluginDrivers.Keys.Distinct())
|
||||||
|
{
|
||||||
|
var filtered = FilterPluginDevices(data, plugin, deviceDicts, channelDicts);
|
||||||
|
var pluginName = PluginServiceUtil.GetFileNameAndTypeName(plugin).Item2;
|
||||||
|
sheets.Add(pluginName, GetPluginSheets(filtered, deviceDicts, channelDicts, plugin, pluginDrivers, propertysDict));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEnumerable<Dictionary<string, object>> GetVariableSheets(
|
||||||
|
IEnumerable<Variable> data,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
string? deviceName)
|
||||||
|
{
|
||||||
|
var type = typeof(Variable);
|
||||||
|
var propertyInfos = type.GetRuntimeProperties()
|
||||||
|
.Where(a => a.GetCustomAttribute<IgnoreExcelAttribute>(false) == null)
|
||||||
|
.OrderBy(a =>
|
||||||
|
{
|
||||||
|
var order = a.GetCustomAttribute<AutoGenerateColumnAttribute>()?.Order ?? int.MaxValue;
|
||||||
|
if (order < 0) order += 10000000;
|
||||||
|
else if (order == 0) order = 10000000;
|
||||||
|
return order;
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var variable in data)
|
||||||
|
{
|
||||||
|
yield return GetVariable(deviceDicts, deviceName, type, propertyInfos, variable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, object> GetVariable(Dictionary<long, Device> deviceDicts, string? deviceName, Type type, IOrderedEnumerable<PropertyInfo> propertyInfos, Variable variable)
|
||||||
|
{
|
||||||
|
var row = new Dictionary<string, object>();
|
||||||
|
deviceDicts.TryGetValue(variable.DeviceId, out var device);
|
||||||
|
row.TryAdd(ExportString.DeviceName, device?.Name ?? deviceName);
|
||||||
|
|
||||||
|
foreach (var item in propertyInfos)
|
||||||
|
{
|
||||||
|
var desc = type.GetPropertyDisplayName(item.Name);
|
||||||
|
row.TryAdd(desc ?? item.Name, item.GetValue(variable)?.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEnumerable<Dictionary<string, object>> GetPluginSheets(
|
||||||
|
IEnumerable<Variable> data,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
Dictionary<long, Channel> channelDicts,
|
||||||
|
string plugin,
|
||||||
|
Dictionary<string, VariablePropertyBase> pluginDrivers,
|
||||||
|
ConcurrentDictionary<string, (VariablePropertyBase, Dictionary<string, PropertyInfo>)> propertysDict)
|
||||||
|
{
|
||||||
|
if (!pluginDrivers.TryGetValue(plugin, out var variablePropertyBase))
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
if (!propertysDict.TryGetValue(plugin, out var propertys))
|
||||||
|
{
|
||||||
|
var driverProperties = variablePropertyBase;
|
||||||
|
var driverPropertyType = driverProperties.GetType();
|
||||||
|
propertys.Item1 = driverProperties;
|
||||||
|
propertys.Item2 = driverPropertyType.GetRuntimeProperties()
|
||||||
|
.Where(a => a.GetCustomAttribute<DynamicPropertyAttribute>() != null)
|
||||||
|
.ToDictionary(
|
||||||
|
a => driverPropertyType.GetPropertyDisplayName(a.Name, a => a.GetCustomAttribute<DynamicPropertyAttribute>(true)?.Description));
|
||||||
|
propertysDict.TryAdd(plugin, propertys);
|
||||||
|
}
|
||||||
|
if (propertys.Item2?.Count == null || propertys.Item2?.Count == 0)
|
||||||
|
{
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
foreach (var variable in data)
|
||||||
|
{
|
||||||
|
if (variable.VariablePropertys == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var item in variable.VariablePropertys)
|
||||||
|
{
|
||||||
|
if (!(deviceDicts.TryGetValue(item.Key, out var businessDevice) &&
|
||||||
|
deviceDicts.TryGetValue(variable.DeviceId, out var collectDevice)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
channelDicts.TryGetValue(businessDevice.ChannelId, out var channel);
|
||||||
|
if (channel?.PluginName != plugin)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
yield return GetPlugin(propertys, variable, item, businessDevice, collectDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, object> GetPlugin((VariablePropertyBase, Dictionary<string, PropertyInfo>) propertys, Variable variable, KeyValuePair<long, Dictionary<string, string>> item, Device businessDevice, Device collectDevice)
|
||||||
|
{
|
||||||
|
var row = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ ExportString.DeviceName, collectDevice.Name },
|
||||||
|
{ ExportString.BusinessDeviceName, businessDevice.Name },
|
||||||
|
{ ExportString.VariableName, variable.Name }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var kv in propertys.Item2)
|
||||||
|
{
|
||||||
|
var propDict = item.Value;
|
||||||
|
if (propDict.TryGetValue(kv.Value.Name, out var dependencyProperty))
|
||||||
|
{
|
||||||
|
row.TryAdd(kv.Key, dependencyProperty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
row.TryAdd(kv.Key, ThingsGatewayStringConverter.Default.Serialize(null, kv.Value.GetValue(propertys.Item1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, object> ExportSheets(
|
||||||
|
IAsyncEnumerable<Variable> data,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
Dictionary<long, Channel> channelDicts,
|
||||||
|
Dictionary<string, VariablePropertyBase> pluginDrivers,
|
||||||
|
string? deviceName = null)
|
||||||
|
{
|
||||||
|
var sheets = new Dictionary<string, object>();
|
||||||
|
var propertysDict = new ConcurrentDictionary<string, (VariablePropertyBase, Dictionary<string, PropertyInfo>)>();
|
||||||
|
|
||||||
|
// 主变量页
|
||||||
|
sheets.Add(ExportString.VariableName, GetVariableSheets(data, deviceDicts, deviceName));
|
||||||
|
|
||||||
|
// 插件页(动态推导)
|
||||||
|
foreach (var plugin in pluginDrivers.Keys.Distinct())
|
||||||
|
{
|
||||||
|
var filtered = FilterPluginDevices(data, plugin, deviceDicts, channelDicts);
|
||||||
|
var pluginName = PluginServiceUtil.GetFileNameAndTypeName(plugin).Item2;
|
||||||
|
sheets.Add(pluginName, GetPluginSheets(filtered, deviceDicts, channelDicts, plugin, pluginDrivers, propertysDict));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async IAsyncEnumerable<Dictionary<string, object>> GetVariableSheets(
|
||||||
|
IAsyncEnumerable<Variable> data,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
string? deviceName)
|
||||||
|
{
|
||||||
|
var type = typeof(Variable);
|
||||||
|
var propertyInfos = type.GetRuntimeProperties()
|
||||||
|
.Where(a => a.GetCustomAttribute<IgnoreExcelAttribute>(false) == null)
|
||||||
|
.OrderBy(a =>
|
||||||
|
{
|
||||||
|
var order = a.GetCustomAttribute<AutoGenerateColumnAttribute>()?.Order ?? int.MaxValue;
|
||||||
|
if (order < 0) order += 10000000;
|
||||||
|
else if (order == 0) order = 10000000;
|
||||||
|
return order;
|
||||||
|
});
|
||||||
|
|
||||||
|
await foreach (var variable in data.ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
yield return GetVariable(deviceDicts, deviceName, type, propertyInfos, variable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async IAsyncEnumerable<Dictionary<string, object>> GetPluginSheets(
|
||||||
|
IAsyncEnumerable<Variable> data,
|
||||||
|
Dictionary<long, Device> deviceDicts,
|
||||||
|
Dictionary<long, Channel> channelDicts,
|
||||||
|
string plugin,
|
||||||
|
Dictionary<string, VariablePropertyBase> pluginDrivers,
|
||||||
|
ConcurrentDictionary<string, (VariablePropertyBase, Dictionary<string, PropertyInfo>)> propertysDict)
|
||||||
|
{
|
||||||
|
if (!pluginDrivers.TryGetValue(plugin, out var variablePropertyBase))
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
if (!propertysDict.TryGetValue(plugin, out var propertys))
|
||||||
|
{
|
||||||
|
var driverProperties = variablePropertyBase;
|
||||||
|
var driverPropertyType = driverProperties.GetType();
|
||||||
|
propertys.Item1 = driverProperties;
|
||||||
|
propertys.Item2 = driverPropertyType.GetRuntimeProperties()
|
||||||
|
.Where(a => a.GetCustomAttribute<DynamicPropertyAttribute>() != null)
|
||||||
|
.ToDictionary(
|
||||||
|
a => driverPropertyType.GetPropertyDisplayName(a.Name, a => a.GetCustomAttribute<DynamicPropertyAttribute>(true)?.Description));
|
||||||
|
propertysDict.TryAdd(plugin, propertys);
|
||||||
|
}
|
||||||
|
if (propertys.Item2?.Count == null || propertys.Item2?.Count == 0)
|
||||||
|
{
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
await foreach (var variable in data.ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
if (variable.VariablePropertys == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var item in variable.VariablePropertys)
|
||||||
|
{
|
||||||
|
if (!(deviceDicts.TryGetValue(item.Key, out var businessDevice) &&
|
||||||
|
deviceDicts.TryGetValue(variable.DeviceId, out var collectDevice)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
channelDicts.TryGetValue(businessDevice.ChannelId, out var channel);
|
||||||
|
if (channel?.PluginName != plugin)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
yield return GetPlugin(propertys, variable, item, businessDevice, collectDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<Dictionary<string, object>> ExportCoreAsync(IEnumerable<Variable> data, string deviceName = null, string sortName = nameof(Variable.Id), SortOrder sortOrder = SortOrder.Asc)
|
public static async Task<Dictionary<string, object>> ExportCoreAsync(IEnumerable<Variable> data, string deviceName = null, string sortName = nameof(Variable.Id), SortOrder sortOrder = SortOrder.Asc)
|
||||||
{
|
{
|
||||||
@@ -67,7 +350,6 @@ public static class VariableServiceHelpers
|
|||||||
;
|
;
|
||||||
|
|
||||||
#endregion 列名称
|
#endregion 列名称
|
||||||
var varName = nameof(Variable.Name);
|
|
||||||
data.ParallelForEachStreamed((variable, state, index) =>
|
data.ParallelForEachStreamed((variable, state, index) =>
|
||||||
{
|
{
|
||||||
Dictionary<string, object> varExport = new();
|
Dictionary<string, object> varExport = new();
|
||||||
@@ -83,10 +365,6 @@ public static class VariableServiceHelpers
|
|||||||
}
|
}
|
||||||
//描述
|
//描述
|
||||||
var desc = type.GetPropertyDisplayName(item.Name);
|
var desc = type.GetPropertyDisplayName(item.Name);
|
||||||
if (item.Name == varName)
|
|
||||||
{
|
|
||||||
varName = desc;
|
|
||||||
}
|
|
||||||
//数据源增加
|
//数据源增加
|
||||||
varExport.TryAdd(desc ?? item.Name, item.GetValue(variable)?.ToString());
|
varExport.TryAdd(desc ?? item.Name, item.GetValue(variable)?.ToString());
|
||||||
}
|
}
|
||||||
@@ -128,7 +406,8 @@ public static class VariableServiceHelpers
|
|||||||
var variablePropertyType = variableProperty.GetType();
|
var variablePropertyType = variableProperty.GetType();
|
||||||
propertys.Item2 = variablePropertyType.GetRuntimeProperties()
|
propertys.Item2 = variablePropertyType.GetRuntimeProperties()
|
||||||
.Where(a => a.GetCustomAttribute<DynamicPropertyAttribute>() != null)
|
.Where(a => a.GetCustomAttribute<DynamicPropertyAttribute>() != null)
|
||||||
.ToDictionary(a => variablePropertyType.GetPropertyDisplayName(a.Name, a => a.GetCustomAttribute<DynamicPropertyAttribute>(true)?.Description));
|
.ToDictionary(a => variablePropertyType.GetPropertyDisplayName(a.Name, a =>
|
||||||
|
a.GetCustomAttribute<DynamicPropertyAttribute>(true)?.Description));
|
||||||
propertysDict.TryAdd(channel.PluginName, propertys);
|
propertysDict.TryAdd(channel.PluginName, propertys);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -263,7 +542,7 @@ public static class VariableServiceHelpers
|
|||||||
rows.Add(expando);
|
rows.Add(expando);
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceImportPreview = await GlobalData.VariableService.SetVariableData(dataScope, deviceDicts, ImportPreviews, deviceImportPreview, driverPluginNameDict, propertysDict, sheetName, rows).ConfigureAwait(false);
|
deviceImportPreview = GlobalData.VariableService.SetVariableData(dataScope, deviceDicts, ImportPreviews, deviceImportPreview, driverPluginNameDict, propertysDict, sheetName, rows);
|
||||||
if (ImportPreviews.Any(a => a.Value.HasError))
|
if (ImportPreviews.Any(a => a.Value.HasError))
|
||||||
{
|
{
|
||||||
throw new(ImportPreviews.FirstOrDefault(a => a.Value.HasError).Value.Results.FirstOrDefault(a => !a.Success).ErrorMessage ?? "error");
|
throw new(ImportPreviews.FirstOrDefault(a => a.Value.HasError).Value.Results.FirstOrDefault(a => !a.Success).ErrorMessage ?? "error");
|
||||||
|
|||||||
@@ -39,48 +39,55 @@
|
|||||||
<TableColumn @bind-Field="@context.LogLevel" Filterable=true Sortable=true Visible="false" />
|
<TableColumn @bind-Field="@context.LogLevel" Filterable=true Sortable=true Visible="false" />
|
||||||
<TableColumn @bind-Field="@context.ChannelType" Filterable=true Sortable=true Visible="false" />
|
<TableColumn @bind-Field="@context.ChannelType" Filterable=true Sortable=true Visible="false" />
|
||||||
|
|
||||||
<TableColumn Field="@context.CacheTimeout" FieldExpression=@(()=>context.CacheTimeout) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.CacheTimeout" FieldExpression=@(() => context.CacheTimeout) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.CheckClearTime" FieldExpression=@(()=>context.CheckClearTime) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.CheckClearTime" FieldExpression=@(() => context.CheckClearTime) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.ConnectTimeout" FieldExpression=@(()=>context.ConnectTimeout) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.ConnectTimeout" FieldExpression=@(() => context.ConnectTimeout) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.Heartbeat" FieldExpression=@(()=>context.Heartbeat) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.Heartbeat" FieldExpression=@(() => context.Heartbeat) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.HeartbeatTime" FieldExpression=@(()=>context.HeartbeatTime) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.HeartbeatTime" FieldExpression=@(() => context.HeartbeatTime) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.DtuSeviceType" FieldExpression=@(()=>context.DtuSeviceType) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.DtuSeviceType" FieldExpression=@(() => context.DtuSeviceType) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.DtuId" FieldExpression=@(()=>context.DtuId) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.DtuId" FieldExpression=@(() => context.DtuId) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
|
|
||||||
<TableColumn Field="@context.PluginType" FieldExpression=@(()=>context.PluginType) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.PluginType" FieldExpression=@(() => context.PluginType) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.PortName" FieldExpression=@(()=>context.PortName) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.PortName" FieldExpression=@(() => context.PortName) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RemoteUrl" FieldExpression=@(()=>context.RemoteUrl) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.RemoteUrl" FieldExpression=@(() => context.RemoteUrl) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.BindUrl" FieldExpression=@(()=>context.BindUrl) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.BindUrl" FieldExpression=@(() => context.BindUrl) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.MaxClientCount" FieldExpression=@(()=>context.MaxClientCount) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.MaxClientCount" FieldExpression=@(() => context.MaxClientCount) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.MaxConcurrentCount" FieldExpression=@(()=>context.MaxConcurrentCount) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.MaxConcurrentCount" FieldExpression=@(() => context.MaxConcurrentCount) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
|
|
||||||
<TableColumn @bind-Field="@context.Id" Filterable=true Sortable=true Visible="false" DefaultSort=true DefaultSortOrder="SortOrder.Asc" />
|
<TableColumn @bind-Field="@context.Id" Filterable=true Sortable=true Visible="false" DefaultSort=true DefaultSortOrder="SortOrder.Asc" />
|
||||||
|
|
||||||
</TableColumns>
|
</TableColumns>
|
||||||
|
|
||||||
<EditTemplate Context="context">
|
<EditTemplate Context="context">
|
||||||
<ChannelEditComponent Model=@(context) ValidateEnable=false BatchEditEnable=false PluginType="ChannelDeviceHelpers.GetPluginType( SelectModel)"></ChannelEditComponent>
|
<ChannelEditComponent Model=@(context) ValidateEnable=false BatchEditEnable=false PluginType="ChannelDeviceHelpers.GetPluginType(SelectModel)"></ChannelEditComponent>
|
||||||
</EditTemplate>
|
</EditTemplate>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ExportButtonDropdownTemplate Context="ExportContext">
|
<ExportButtonDropdownTemplate Context="ExportContext">
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext,true)" IsDisabled=@(!AuthorizeButton("导出"))>
|
@if ((AuthorizeButton("导出")))
|
||||||
<i class="fas fa-file-export"></i>
|
{
|
||||||
<span>@RazorLocalizer["ExportAll"]</span>
|
|
||||||
</Button>
|
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext, true)" IsKeepDisabled=@(!AuthorizeButton("导出"))>
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导出"))>
|
<i class="fas fa-file-export"></i>
|
||||||
<i class="fas fa-file-export"></i>
|
<span>@RazorLocalizer["ExportAll"]</span>
|
||||||
<span>@RazorLocalizer["TablesExportButtonExcelText"]</span>
|
</Button>
|
||||||
</Button>
|
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导出"))>
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelImportAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导入"))>
|
<i class="fas fa-file-export"></i>
|
||||||
<i class="fas fa-file-import"></i>
|
<span>@RazorLocalizer["TablesExportButtonExcelText"]</span>
|
||||||
<span>@RazorLocalizer["TablesImportButtonExcelText"]</span>
|
</Button>
|
||||||
</Button>
|
}
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelChannelAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导入"))>
|
@if ((AuthorizeButton("导入")))
|
||||||
<i class="fas fa-file-import"></i>
|
{
|
||||||
<span>@GatewayLocalizer["ExcelChannel"]</span>
|
<Button class="dropdown-item" OnClick="() => ExcelImportAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导入"))>
|
||||||
</Button>
|
<i class="fas fa-file-import"></i>
|
||||||
|
<span>@RazorLocalizer["TablesImportButtonExcelText"]</span>
|
||||||
|
</Button>
|
||||||
|
<Button class="dropdown-item" OnClick="() => ExcelChannelAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导入"))>
|
||||||
|
<i class="fas fa-file-import"></i>
|
||||||
|
<span>@GatewayLocalizer["ExcelChannel"]</span>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
</ExportButtonDropdownTemplate>
|
</ExportButtonDropdownTemplate>
|
||||||
<TableToolbarTemplate>
|
<TableToolbarTemplate>
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,10 @@
|
|||||||
IsPagination=true>
|
IsPagination=true>
|
||||||
<TableColumns>
|
<TableColumns>
|
||||||
|
|
||||||
<TableColumn Field="@context.Name" FieldExpression=@(()=>context.Name) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.Name" FieldExpression=@(() => context.Name) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn Field="@context.Description" FieldExpression=@(()=>context.Description) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.Description" FieldExpression=@(() => context.Description) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn Field="@context.IntervalTime" FieldExpression=@(()=>context.IntervalTime) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.IntervalTime" FieldExpression=@(() => context.IntervalTime) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.ChannelName" FieldExpression=@(()=>context.ChannelName) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.ChannelName" FieldExpression=@(() => context.ChannelName) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn @bind-Field="@context.Enable" Filterable=true Sortable=true Visible="true" />
|
<TableColumn @bind-Field="@context.Enable" Filterable=true Sortable=true Visible="true" />
|
||||||
<TableColumn @bind-Field="@context.LogLevel" Filterable=true Sortable=true Visible="false" />
|
<TableColumn @bind-Field="@context.LogLevel" Filterable=true Sortable=true Visible="false" />
|
||||||
<TableColumn @bind-Field="@context.Remark1" Filterable=true Sortable=true Visible="false" />
|
<TableColumn @bind-Field="@context.Remark1" Filterable=true Sortable=true Visible="false" />
|
||||||
@@ -40,25 +40,25 @@
|
|||||||
<TableColumn @bind-Field="@context.Remark4" Filterable=true Sortable=true Visible="false" />
|
<TableColumn @bind-Field="@context.Remark4" Filterable=true Sortable=true Visible="false" />
|
||||||
<TableColumn @bind-Field="@context.Remark5" Filterable=true Sortable=true Visible="false" />
|
<TableColumn @bind-Field="@context.Remark5" Filterable=true Sortable=true Visible="false" />
|
||||||
|
|
||||||
<TableColumn Field="@context.ActiveTime" FieldExpression=@(()=>context.ActiveTime) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.ActiveTime" FieldExpression=@(() => context.ActiveTime) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn Field="@context.DeviceStatus" FieldExpression=@(()=>context.DeviceStatus) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.DeviceStatus" FieldExpression=@(() => context.DeviceStatus) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
|
|
||||||
<TableColumn Field="@context.Pause" FieldExpression=@(()=>context.Pause) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.Pause" FieldExpression=@(() => context.Pause) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.LastErrorMessage" FieldExpression=@(()=>context.LastErrorMessage) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.LastErrorMessage" FieldExpression=@(() => context.LastErrorMessage) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
|
|
||||||
<TableColumn Field="@context.PluginName" FieldExpression=@(()=>context.PluginName) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.PluginName" FieldExpression=@(() => context.PluginName) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
|
|
||||||
<TableColumn Field="@context.DeviceVariableCount" FieldExpression=@(()=>context.DeviceVariableCount) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.DeviceVariableCount" FieldExpression=@(() => context.DeviceVariableCount) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn Field="@context.MethodVariableCount" FieldExpression=@(()=>context.MethodVariableCount) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.MethodVariableCount" FieldExpression=@(() => context.MethodVariableCount) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn Field="@context.SourceVariableCount" FieldExpression=@(()=>context.SourceVariableCount) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.SourceVariableCount" FieldExpression=@(() => context.SourceVariableCount) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
|
|
||||||
<TableColumn Field="@context.ChannelId" FieldExpression=@(()=>context.ChannelId) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.ChannelId" FieldExpression=@(() => context.ChannelId) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RedundantEnable" FieldExpression=@(()=>context.RedundantEnable) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.RedundantEnable" FieldExpression=@(() => context.RedundantEnable) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RedundantType" FieldExpression=@(()=>context.RedundantType) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.RedundantType" FieldExpression=@(() => context.RedundantType) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RedundantDeviceId" FieldExpression=@(()=>context.RedundantDeviceId) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.RedundantDeviceId" FieldExpression=@(() => context.RedundantDeviceId) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RedundantScanIntervalTime" FieldExpression=@(()=>context.RedundantScanIntervalTime) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.RedundantScanIntervalTime" FieldExpression=@(() => context.RedundantScanIntervalTime) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RedundantScript" FieldExpression=@(()=>context.RedundantScript) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.RedundantScript" FieldExpression=@(() => context.RedundantScript) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RedundantSwitchType" FieldExpression=@(()=>context.RedundantSwitchType) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.RedundantSwitchType" FieldExpression=@(() => context.RedundantSwitchType) Ignore="true" ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
|
|
||||||
|
|
||||||
<TableColumn @bind-Field="@context.Id" Filterable=true Sortable=true Visible="false" DefaultSort=true DefaultSortOrder="SortOrder.Asc" />
|
<TableColumn @bind-Field="@context.Id" Filterable=true Sortable=true Visible="false" DefaultSort=true DefaultSortOrder="SortOrder.Asc" />
|
||||||
@@ -66,28 +66,35 @@
|
|||||||
</TableColumns>
|
</TableColumns>
|
||||||
|
|
||||||
<EditTemplate Context="context">
|
<EditTemplate Context="context">
|
||||||
<DeviceEditComponent Model=@(context) ValidateEnable=false BatchEditEnable=false AutoRestartThread=AutoRestartThread ></DeviceEditComponent>
|
<DeviceEditComponent Model=@(context) ValidateEnable=false BatchEditEnable=false AutoRestartThread=AutoRestartThread></DeviceEditComponent>
|
||||||
</EditTemplate>
|
</EditTemplate>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ExportButtonDropdownTemplate Context="ExportContext">
|
<ExportButtonDropdownTemplate Context="ExportContext">
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext,true)" IsDisabled=@(!AuthorizeButton("导出"))>
|
|
||||||
<i class="fas fa-file-export"></i>
|
@if ((AuthorizeButton("导出")))
|
||||||
<span>@RazorLocalizer["ExportAll"]</span>
|
{
|
||||||
</Button>
|
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext, true)" IsKeepDisabled=@(!AuthorizeButton("导出"))>
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导出"))>
|
<i class="fas fa-file-export"></i>
|
||||||
<i class="fas fa-file-export"></i>
|
<span>@RazorLocalizer["ExportAll"]</span>
|
||||||
<span>@RazorLocalizer["TablesExportButtonExcelText"]</span>
|
</Button>
|
||||||
</Button>
|
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导出"))>
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelImportAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导入"))>
|
<i class="fas fa-file-export"></i>
|
||||||
<i class="fas fa-file-import"></i>
|
<span>@RazorLocalizer["TablesExportButtonExcelText"]</span>
|
||||||
<span>@RazorLocalizer["TablesImportButtonExcelText"]</span>
|
</Button>
|
||||||
</Button>
|
}
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelDeviceAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导入"))>
|
@if ((AuthorizeButton("导入")))
|
||||||
<i class="fas fa-file-import"></i>
|
{
|
||||||
<span>@GatewayLocalizer["ExcelDevice"]</span>
|
<Button class="dropdown-item" OnClick="() => ExcelImportAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导入"))>
|
||||||
</Button>
|
<i class="fas fa-file-import"></i>
|
||||||
|
<span>@RazorLocalizer["TablesImportButtonExcelText"]</span>
|
||||||
|
</Button>
|
||||||
|
<Button class="dropdown-item" OnClick="() => ExcelDeviceAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导入"))>
|
||||||
|
<i class="fas fa-file-import"></i>
|
||||||
|
<span>@GatewayLocalizer["ExcelDevice"]</span>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
</ExportButtonDropdownTemplate>
|
</ExportButtonDropdownTemplate>
|
||||||
<TableToolbarTemplate>
|
<TableToolbarTemplate>
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
OnQueryAsync="OnQueryAsync"
|
OnQueryAsync="OnQueryAsync"
|
||||||
IsPagination=true>
|
IsPagination=true>
|
||||||
<TableColumns>
|
<TableColumns>
|
||||||
<TableColumn Field="@context.DeviceId" FieldExpression=@(()=>context.DeviceId) ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.DeviceId" FieldExpression=@(() => context.DeviceId) ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.DeviceName" FieldExpression=@(()=>context.DeviceName) ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.DeviceName" FieldExpression=@(() => context.DeviceName) ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn @bind-Field="@context.Name" ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn @bind-Field="@context.Name" ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn @bind-Field="@context.Description" ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn @bind-Field="@context.Description" ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn @bind-Field="@context.BusinessGroup" ShowTips=true Filterable=true Sortable=true Visible=true />
|
<TableColumn @bind-Field="@context.BusinessGroup" ShowTips=true Filterable=true Sortable=true Visible=true />
|
||||||
@@ -38,19 +38,19 @@
|
|||||||
<TableColumn @bind-Field="@context.RpcWriteCheck" ShowTips=true Filterable=true Sortable=true Visible=false />
|
<TableColumn @bind-Field="@context.RpcWriteCheck" ShowTips=true Filterable=true Sortable=true Visible=false />
|
||||||
|
|
||||||
<TableColumn @bind-Field="@context.Enable" Filterable=true Sortable=true Visible="false" />
|
<TableColumn @bind-Field="@context.Enable" Filterable=true Sortable=true Visible="false" />
|
||||||
<TableColumn Field="@context.ChangeTime" ShowTips=true FieldExpression=@(()=>context.ChangeTime) Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.ChangeTime" ShowTips=true FieldExpression=@(() => context.ChangeTime) Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.CollectTime" ShowTips=true FieldExpression=@(()=>context.CollectTime) Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.CollectTime" ShowTips=true FieldExpression=@(() => context.CollectTime) Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn Field="@context.IsOnline" FieldExpression=@(()=>context.IsOnline) Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.IsOnline" FieldExpression=@(() => context.IsOnline) Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn Field="@context.LastErrorMessage" ShowTips=true FieldExpression=@(()=>context.LastErrorMessage) Filterable=true Sortable=true Visible=false />
|
<TableColumn Field="@context.LastErrorMessage" ShowTips=true FieldExpression=@(() => context.LastErrorMessage) Filterable=true Sortable=true Visible=false />
|
||||||
|
|
||||||
<TableColumn Field="@context.LastSetValue" FieldExpression=@(()=>context.LastSetValue) Visible=false ShowTips=true Formatter=@(JsonFormatter) />
|
<TableColumn Field="@context.LastSetValue" FieldExpression=@(() => context.LastSetValue) Visible=false ShowTips=true Formatter=@(JsonFormatter) />
|
||||||
|
|
||||||
<TableColumn Field="@context.RawValue" FieldExpression=@(()=>context.RawValue) Visible=false ShowTips=true Formatter=@(JsonFormatter) />
|
<TableColumn Field="@context.RawValue" FieldExpression=@(() => context.RawValue) Visible=false ShowTips=true Formatter=@(JsonFormatter) />
|
||||||
<TableColumn Field="@context.Value" FieldExpression=@(()=>context.Value) Visible=true ShowTips=true Formatter=@(JsonFormatter) />
|
<TableColumn Field="@context.Value" FieldExpression=@(() => context.Value) Visible=true ShowTips=true Formatter=@(JsonFormatter) />
|
||||||
|
|
||||||
<TableColumn @bind-Field="@context.SaveValue" Filterable=true Sortable=true Visible=false />
|
<TableColumn @bind-Field="@context.SaveValue" Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn @bind-Field="@context.DataType" Filterable=true Sortable=true Visible=false />
|
<TableColumn @bind-Field="@context.DataType" Filterable=true Sortable=true Visible=false />
|
||||||
<TableColumn Field="@context.RuntimeType" ShowTips=true FieldExpression=@(()=>context.RuntimeType) Filterable=true Sortable=true Visible=true />
|
<TableColumn Field="@context.RuntimeType" ShowTips=true FieldExpression=@(() => context.RuntimeType) Filterable=true Sortable=true Visible=true />
|
||||||
|
|
||||||
<TableColumn @bind-Field="@context.RegisterAddress" Filterable=true Sortable=true Visible=true />
|
<TableColumn @bind-Field="@context.RegisterAddress" Filterable=true Sortable=true Visible=true />
|
||||||
<TableColumn @bind-Field="@context.ArrayLength" Filterable=true Sortable=true Visible=false />
|
<TableColumn @bind-Field="@context.ArrayLength" Filterable=true Sortable=true Visible=false />
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
</TableColumns>
|
</TableColumns>
|
||||||
<RowButtonTemplate>
|
<RowButtonTemplate>
|
||||||
|
|
||||||
<PopConfirmButton IsDisabled=@(!AuthorizeButton("写入变量")) Size="Size.ExtraSmall" Color="Color.Warning" Icon="fa-solid fa-bars" Text="@Localizer["WriteVariable"]" IsAsync OnConfirm="()=>OnWriteVariable(context)">
|
<PopConfirmButton IsDisabled=@(!AuthorizeButton("写入变量")) Size="Size.ExtraSmall" Color="Color.Warning" Icon="fa-solid fa-bars" Text="@Localizer["WriteVariable"]" IsAsync OnConfirm="() => OnWriteVariable(context)">
|
||||||
|
|
||||||
<BodyTemplate>
|
<BodyTemplate>
|
||||||
<Textarea @bind-Value=WriteValue ShowLabel="true" ShowLabelTooltip="true" />
|
<Textarea @bind-Value=WriteValue ShowLabel="true" ShowLabelTooltip="true" />
|
||||||
@@ -85,22 +85,28 @@
|
|||||||
|
|
||||||
|
|
||||||
<ExportButtonDropdownTemplate Context="ExportContext">
|
<ExportButtonDropdownTemplate Context="ExportContext">
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext,true)" IsDisabled=@(!AuthorizeButton("导出"))>
|
@if ((AuthorizeButton("导出")))
|
||||||
<i class="fas fa-file-export"></i>
|
{
|
||||||
<span>@RazorLocalizer["ExportAll"]</span>
|
<Button IsAsync class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext, true)" IsKeepDisabled=@(!AuthorizeButton("导出"))>
|
||||||
</Button>
|
<i class="fas fa-file-export"></i>
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导出"))>
|
<span>@RazorLocalizer["ExportAll"]</span>
|
||||||
<i class="fas fa-file-export"></i>
|
</Button>
|
||||||
<span>@RazorLocalizer["TablesExportButtonExcelText"]</span>
|
<Button class="dropdown-item" OnClick="() => ExcelExportAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导出"))>
|
||||||
</Button>
|
<i class="fas fa-file-export"></i>
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelImportAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导入"))>
|
<span>@RazorLocalizer["TablesExportButtonExcelText"]</span>
|
||||||
<i class="fas fa-file-import"></i>
|
</Button>
|
||||||
<span>@RazorLocalizer["TablesImportButtonExcelText"]</span>
|
}
|
||||||
</Button>
|
@if ((AuthorizeButton("导入")))
|
||||||
<Button class="dropdown-item" OnClick="() => ExcelVariableAsync(ExportContext)" IsDisabled=@(!AuthorizeButton("导入"))>
|
{
|
||||||
<i class="fas fa-file-import"></i>
|
<Button class="dropdown-item" OnClick="() => ExcelImportAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导入"))>
|
||||||
<span>@GatewayLocalizer["ExcelVariable"]</span>
|
<i class="fas fa-file-import"></i>
|
||||||
</Button>
|
<span>@RazorLocalizer["TablesImportButtonExcelText"]</span>
|
||||||
|
</Button>
|
||||||
|
<Button class="dropdown-item" OnClick="() => ExcelVariableAsync(ExportContext)" IsKeepDisabled=@(!AuthorizeButton("导入"))>
|
||||||
|
<i class="fas fa-file-import"></i>
|
||||||
|
<span>@GatewayLocalizer["ExcelVariable"]</span>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
</ExportButtonDropdownTemplate>
|
</ExportButtonDropdownTemplate>
|
||||||
<TableToolbarTemplate>
|
<TableToolbarTemplate>
|
||||||
|
|
||||||
|
|||||||
@@ -410,7 +410,6 @@ finally
|
|||||||
});
|
});
|
||||||
await DialogService.Show(op);
|
await DialogService.Show(op);
|
||||||
|
|
||||||
_ = Task.Run(GlobalData.VariableRuntimeService.PreheatCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion 导出
|
#endregion 导出
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public class Startup : AppStartup
|
|||||||
.AddHubOptions(options =>
|
.AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize = 32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
@@ -127,7 +127,7 @@ public class Startup : AppStartup
|
|||||||
}).AddHubOptions(options =>
|
}).AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize = 32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public class Startup : AppStartup
|
|||||||
.AddHubOptions(options =>
|
.AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize = 32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
@@ -127,7 +127,7 @@ public class Startup : AppStartup
|
|||||||
}).AddHubOptions(options =>
|
}).AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize =32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class Startup : AppStartup
|
|||||||
.AddHubOptions(options =>
|
.AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize = 32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
@@ -124,7 +124,7 @@ public class Startup : AppStartup
|
|||||||
}).AddHubOptions(options =>
|
}).AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
//单个传入集线器消息的最大大小。默认 32 KB
|
//单个传入集线器消息的最大大小。默认 32 KB
|
||||||
options.MaximumReceiveMessageSize = 1024 * 1024;
|
options.MaximumReceiveMessageSize = 32 * 1024 * 1024;
|
||||||
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
//可为客户端上载流缓冲的最大项数。 如果达到此限制,则会阻止处理调用,直到服务器处理流项。
|
||||||
options.StreamBufferCapacity = 30;
|
options.StreamBufferCapacity = 30;
|
||||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
options.ClientTimeoutInterval = TimeSpan.FromMinutes(2);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>10.9.15</Version>
|
<Version>10.9.16</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user