优化导入excel效率
This commit is contained in:
@@ -362,13 +362,13 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
|
|||||||
var result1 = SendThenResponse(ISO_CR);
|
var result1 = SendThenResponse(ISO_CR);
|
||||||
if (!result1.IsSuccess)
|
if (!result1.IsSuccess)
|
||||||
{
|
{
|
||||||
Logger?.Error(client.IP + ":" + client.Port + "ISO初始化失败");
|
Logger?.Warning(client.IP + ":" + client.Port + "-ISO初始化失败:" + result1.Message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var result2 = SendThenResponse(S7_PN);
|
var result2 = SendThenResponse(S7_PN);
|
||||||
if (!result2.IsSuccess)
|
if (!result2.IsSuccess)
|
||||||
{
|
{
|
||||||
Logger?.Error(client.IP + ":" + client.Port + "初始化失败");
|
Logger?.Warning(client.IP + ":" + client.Port + "-初始化失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pdu_length = ThingsGatewayBitConverter.ToUInt16(result2.Content.SelectLast(2), 0);
|
pdu_length = ThingsGatewayBitConverter.ToUInt16(result2.Content.SelectLast(2), 0);
|
||||||
|
|||||||
@@ -43,13 +43,14 @@ public abstract class S7 : CollectBase
|
|||||||
|
|
||||||
public override Task AfterStopAsync()
|
public override Task AfterStopAsync()
|
||||||
{
|
{
|
||||||
_plc?.Disconnect();
|
if (_plc != null)
|
||||||
|
_plc?.Disconnect();
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task BeforStartAsync(CancellationToken cancellationToken)
|
public override async Task BeforStartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await _plc.ConnectAsync(cancellationToken);
|
await _plc?.ConnectAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
|
|||||||
@@ -18,13 +18,12 @@ public class ImportPreviewOutputBase
|
|||||||
/// 是否有错误
|
/// 是否有错误
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasError { get; set; }
|
public bool HasError { get; set; }
|
||||||
public virtual int DataCount { get; }
|
public int DataCount { get => Results.Count; }
|
||||||
public virtual List<(int row, bool isSuccess, string resultString)> Results { get; set; } = new();
|
public TGConcurrentList<(int row, bool isSuccess, string resultString)> Results { get; set; } = new();
|
||||||
}
|
}
|
||||||
public class ImportPreviewOutput<T> : ImportPreviewOutputBase where T : class
|
public class ImportPreviewOutput<T> : ImportPreviewOutputBase where T : class
|
||||||
{
|
{
|
||||||
public override int DataCount { get => Data == null ? 0 : Data.Count; }
|
public Dictionary<string, T> Data { get; set; } = new();
|
||||||
public List<T> Data { get; set; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
688
src/ThingsGateway.Core/BaseOutput/TGConcurrentList.cs
Normal file
688
src/ThingsGateway.Core/BaseOutput/TGConcurrentList.cs
Normal file
@@ -0,0 +1,688 @@
|
|||||||
|
#region copyright
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||||
|
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||||
|
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||||
|
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||||
|
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||||
|
// 使用文档:https://diego2098.gitee.io/thingsgateway/
|
||||||
|
// QQ群:605534569
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||||
|
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||||
|
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||||
|
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||||
|
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||||
|
// Github源代码仓库:https://github.com/RRQM
|
||||||
|
// API首页:https://www.yuque.com/rrqm/touchsocket/index
|
||||||
|
// 交流QQ群:234762506
|
||||||
|
// 感谢您的下载和使用
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace ThingsGateway.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 线程安全的List,其基本操作和List一致。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
public class TGConcurrentList<T> : IList<T>
|
||||||
|
{
|
||||||
|
private readonly List<T> m_list;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collection"></param>
|
||||||
|
public TGConcurrentList(IEnumerable<T> collection)
|
||||||
|
{
|
||||||
|
m_list = new List<T>(collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
public TGConcurrentList()
|
||||||
|
{
|
||||||
|
m_list = new List<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="capacity"></param>
|
||||||
|
public TGConcurrentList(int capacity)
|
||||||
|
{
|
||||||
|
m_list = new List<T>(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 元素数量
|
||||||
|
/// </summary>
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为只读
|
||||||
|
/// </summary>
|
||||||
|
public bool IsReadOnly => false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取索引元素
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加元素
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
public void Add(T item)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有元素
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否包含某个元素
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool Contains(T item)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.Contains(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制到
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array"></param>
|
||||||
|
/// <param name="arrayIndex"></param>
|
||||||
|
public void CopyTo(T[] array, int arrayIndex)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.CopyTo(array, arrayIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回迭代器
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IEnumerator<T> GetEnumerator()
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.ToList().GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回迭代器组合
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 索引
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int IndexOf(T item)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.IndexOf(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 插入
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
public void Insert(int index, T item)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Insert(index, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除元素
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool Remove(T item)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.Remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按索引移除
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
public void RemoveAt(int index)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
if (index < m_list.Count)
|
||||||
|
{
|
||||||
|
m_list.RemoveAt(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置容量
|
||||||
|
/// </summary>
|
||||||
|
public int Capacity
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.Capacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Capacity = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.AddRange(IEnumerable{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collection"></param>
|
||||||
|
public void AddRange(IEnumerable<T> collection)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.AddRange(collection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.BinarySearch(T)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int BinarySearch(T item)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.BinarySearch(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.BinarySearch(T, IComparer{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <param name="comparer"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int BinarySearch(T item, IComparer<T> comparer)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.BinarySearch(item, comparer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.BinarySearch(int, int, T, IComparer{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <param name="comparer"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.BinarySearch(index, count, item, comparer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.ConvertAll{TOutput}(Converter{T, TOutput})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TOutput"></typeparam>
|
||||||
|
/// <param name="converter"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.ConvertAll(converter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.Find(Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T Find(Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.Find(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindAll(Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<T> FindAll(Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindAll(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindIndex(int, int, Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startIndex"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int FindIndex(int startIndex, int count, Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindIndex(startIndex, count, match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindIndex(int, Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startIndex"></param>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int FindIndex(int startIndex, Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindIndex(startIndex, match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindIndex(Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int FindIndex(Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindIndex(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindLast(Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T FindLast(Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindLast(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindLastIndex(int, int, Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startIndex"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int FindLastIndex(int startIndex, int count, Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindLastIndex(startIndex, count, match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindLastIndex(int, Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startIndex"></param>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int FindLastIndex(int startIndex, Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindLastIndex(startIndex, match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.FindLastIndex(Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int FindLastIndex(Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.FindLastIndex(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.ForEach(Action{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action"></param>
|
||||||
|
public void ForEach(Action<T> action)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.ForEach(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.GetRange(int, int)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<T> GetRange(int index, int count)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.GetRange(index, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.IndexOf(T, int)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int IndexOf(T item, int index)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.IndexOf(item, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.IndexOf(T, int, int)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int IndexOf(T item, int index, int count)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.IndexOf(item, index, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.InsertRange(int, IEnumerable{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="collection"></param>
|
||||||
|
public void InsertRange(int index, IEnumerable<T> collection)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.InsertRange(index, collection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.LastIndexOf(T)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int LastIndexOf(T item)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.IndexOf(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.LastIndexOf(T, int)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int LastIndexOf(T item, int index)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.LastIndexOf(item, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.LastIndexOf(T, int, int)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int LastIndexOf(T item, int index, int count)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.LastIndexOf(item, index, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.RemoveAll(Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
public void RemoveAll(Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.RemoveAll(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.RemoveRange(int, int)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
public void RemoveRange(int index, int count)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.RemoveRange(index, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.Reverse()"/>
|
||||||
|
/// </summary>
|
||||||
|
public void Reverse()
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.Reverse(int, int)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
public void Reverse(int index, int count)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Reverse(index, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.Sort()"/>
|
||||||
|
/// </summary>
|
||||||
|
public void Sort()
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.Sort(Comparison{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comparison"></param>
|
||||||
|
public void Sort(Comparison<T> comparison)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Sort(comparison);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.Sort(IComparer{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comparer"></param>
|
||||||
|
public void Sort(IComparer<T> comparer)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Sort(comparer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.Sort(int, int, IComparer{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <param name="comparer"></param>
|
||||||
|
public void Sort(int index, int count, IComparer<T> comparer)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.Sort(index, count, comparer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.ToArray"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T[] ToArray()
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.TrimExcess"/>
|
||||||
|
/// </summary>
|
||||||
|
public void TrimExcess()
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
m_list.TrimExcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="List{T}.TrueForAll(Predicate{T})"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool TrueForAll(Predicate<T> match)
|
||||||
|
{
|
||||||
|
lock (((ICollection)m_list).SyncRoot)
|
||||||
|
{
|
||||||
|
return m_list.TrueForAll(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
@@ -473,16 +472,6 @@ namespace ThingsGateway.Core.Extension
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static async Task ForeachAsync<T>(this IEnumerable<T> source, Func<T, Task> action, int maxParallelCount, CancellationToken cancellationToken = default)
|
public static async Task ForeachAsync<T>(this IEnumerable<T> source, Func<T, Task> action, int maxParallelCount, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (Debugger.IsAttached)
|
|
||||||
{
|
|
||||||
foreach (var item in source)
|
|
||||||
{
|
|
||||||
await action(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = new List<Task>();
|
var list = new List<Task>();
|
||||||
foreach (var item in source)
|
foreach (var item in source)
|
||||||
{
|
{
|
||||||
@@ -512,13 +501,7 @@ namespace ThingsGateway.Core.Extension
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Task ForeachAsync<T>(this IEnumerable<T> source, Func<T, Task> action, CancellationToken cancellationToken = default)
|
public static Task ForeachAsync<T>(this IEnumerable<T> source, Func<T, Task> action, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (source is ICollection<T> collection)
|
return ForeachAsync(source, action, source.Count(), cancellationToken);
|
||||||
{
|
|
||||||
return ForeachAsync(collection, action, collection.Count, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = source.ToList();
|
|
||||||
return ForeachAsync(list, action, list.Count, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -621,16 +604,7 @@ namespace ThingsGateway.Core.Extension
|
|||||||
public static async Task ForAsync<T>(this IEnumerable<T> source, Func<T, int, Task> selector, int maxParallelCount, CancellationToken cancellationToken = default)
|
public static async Task ForAsync<T>(this IEnumerable<T> source, Func<T, int, Task> selector, int maxParallelCount, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (Debugger.IsAttached)
|
|
||||||
{
|
|
||||||
foreach (var item in source)
|
|
||||||
{
|
|
||||||
await selector(item, index);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = new List<Task>();
|
var list = new List<Task>();
|
||||||
foreach (var item in source)
|
foreach (var item in source)
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public class OperResult : IRequestInfo, IOperResult
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Exception { get; set; }
|
public string Exception { get; set; }
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool IsSuccess => ResultCode.HasFlag(ResultCode.Success);
|
public bool IsSuccess => ResultCode == ResultCode.Success;
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
using ThingsGateway.Core;
|
using ThingsGateway.Core;
|
||||||
|
|
||||||
namespace ThingsGateway.Web.Foundation;
|
namespace ThingsGateway.Web.Foundation;
|
||||||
@@ -73,7 +75,7 @@ public class MemoryVariable : BaseEntity
|
|||||||
/// 变量额外属性Json,通常使用为上传设备,List属性
|
/// 变量额外属性Json,通常使用为上传设备,List属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(IsJson = true, ColumnName = "VariablePropertys", ColumnDescription = "变量属性Json", IsNullable = true)]
|
[SugarColumn(IsJson = true, ColumnName = "VariablePropertys", ColumnDescription = "变量属性Json", IsNullable = true)]
|
||||||
public Dictionary<long, List<DependencyProperty>> VariablePropertys { get; set; } = new();
|
public ConcurrentDictionary<long, List<DependencyProperty>> VariablePropertys { get; set; } = new();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using ThingsGateway.Core;
|
using ThingsGateway.Core;
|
||||||
|
using ThingsGateway.Foundation.Extension.Generic;
|
||||||
|
|
||||||
namespace ThingsGateway.Web.Foundation;
|
namespace ThingsGateway.Web.Foundation;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 动态类型扩展
|
/// 动态类型扩展
|
||||||
@@ -31,19 +33,18 @@ public static class ExpandoObjectHelpers
|
|||||||
public static T ConvertToEntity<T>(this ExpandoObject expandoObject, bool filter) where T : new()
|
public static T ConvertToEntity<T>(this ExpandoObject expandoObject, bool filter) where T : new()
|
||||||
{
|
{
|
||||||
var entity = new T();
|
var entity = new T();
|
||||||
var properties = typeof(T).GetAllProps().Where(a => !filter || a.GetCustomAttribute<ExcelAttribute>() != null);
|
var properties = typeof(T).GetAllProps().Where(a => !filter || a.GetCustomAttribute<ExcelAttribute>() != null).ToDictionary(a => a.FindDisplayAttribute());
|
||||||
|
|
||||||
foreach (var keyValuePair in (IDictionary<string, object>)expandoObject)
|
expandoObject.ForEach(keyValuePair =>
|
||||||
{
|
{
|
||||||
var property = properties.FirstOrDefault(p => p.FindDisplayAttribute() == keyValuePair.Key);
|
if (properties.TryGetValue(keyValuePair.Key, out var property))
|
||||||
if (property != null)
|
|
||||||
{
|
{
|
||||||
var value = keyValuePair.Value;
|
var value = keyValuePair.Value;
|
||||||
var objValue = property.ObjToTypeValue(value?.ToString() ?? "");
|
var objValue = property.ObjToTypeValue(value?.ToString() ?? "");
|
||||||
property.SetValue(entity, objValue);
|
property.SetValue(entity, objValue);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
});
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public static class ParallelHelpers
|
|||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="source"></param>
|
/// <param name="source"></param>
|
||||||
/// <param name="body"></param>
|
/// <param name="body"></param>
|
||||||
public static void ParallelForEach<T>(this IEnumerable<T> source, Action<T> body) where T : class
|
public static void ParallelForEach<T>(this IEnumerable<T> source, Action<T> body)
|
||||||
{
|
{
|
||||||
Parallel.ForEach(source, _options, variable =>
|
Parallel.ForEach(source, _options, variable =>
|
||||||
{
|
{
|
||||||
@@ -36,4 +36,16 @@ public static class ParallelHelpers
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行<see cref="Parallel.ForEach{TSource}(IEnumerable{TSource}, Action{TSource})"/>
|
||||||
|
/// </summary>
|
||||||
|
public static void ParallelForEach<T>(this IEnumerable<T> source, Action<T> body, int parallelCount)
|
||||||
|
{
|
||||||
|
var options = new ParallelOptions();
|
||||||
|
options.MaxDegreeOfParallelism = parallelCount / 2 == 0 ? 1 : parallelCount;
|
||||||
|
Parallel.ForEach(source, options, variable =>
|
||||||
|
{
|
||||||
|
body(variable);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,13 +16,14 @@ using Microsoft.AspNetCore.Components.Forms;
|
|||||||
|
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
|
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using ThingsGateway.Core;
|
using ThingsGateway.Core;
|
||||||
using ThingsGateway.Core.Extension;
|
using ThingsGateway.Foundation.Extension.Generic;
|
||||||
|
|
||||||
namespace ThingsGateway.Web.Foundation;
|
namespace ThingsGateway.Web.Foundation;
|
||||||
|
|
||||||
@@ -234,29 +235,27 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
if (devId == 0)
|
if (devId == 0)
|
||||||
{
|
{
|
||||||
var devices = GetCacheList().Where(a => a.Enable).ToList();
|
var devices = GetCacheList().Where(a => a.Enable).ToList();
|
||||||
var runtime = devices.Adapt<List<CollectDeviceRunTime>>();
|
var runtime = devices.Adapt<List<CollectDeviceRunTime>>().ToDictionary(a => a.Id);
|
||||||
using var serviceScope = _scopeFactory.CreateScope();
|
using var serviceScope = _scopeFactory.CreateScope();
|
||||||
var variableService = serviceScope.ServiceProvider.GetService<IVariableService>();
|
var variableService = serviceScope.ServiceProvider.GetService<IVariableService>();
|
||||||
var collectVariableRunTimes = await variableService.GetDeviceVariableRuntimeAsync();
|
var collectVariableRunTimes = await variableService.GetDeviceVariableRuntimeAsync();
|
||||||
await runtime.ForeachAsync(device =>
|
ConcurrentDictionary<long, DriverPlugin> driverPlugins = new(_driverPluginService.GetCacheList().ToDictionary(a => a.Id));
|
||||||
{
|
runtime.Values.ParallelForEach(device =>
|
||||||
var pluginName = _driverPluginService.GetNameById(device.PluginId);
|
{
|
||||||
device.PluginName = pluginName;
|
driverPlugins.TryGetValue(device.PluginId, out var driverPlugin);
|
||||||
device.DeviceVariableRunTimes = collectVariableRunTimes.Where(a => a.DeviceId == device.Id).ToList();
|
device.PluginName = driverPlugin?.AssembleName;
|
||||||
return Task.CompletedTask;
|
device.DeviceVariableRunTimes = collectVariableRunTimes.Where(a => a.DeviceId == device.Id).ToList();
|
||||||
});
|
});
|
||||||
|
|
||||||
await collectVariableRunTimes.ForeachAsync(variable =>
|
collectVariableRunTimes.ParallelForEach(variable =>
|
||||||
{
|
{
|
||||||
var device = runtime.FirstOrDefault(a => a.Id == variable.DeviceId);
|
if (runtime.TryGetValue(variable.DeviceId, out var device))
|
||||||
if (device != null)
|
{
|
||||||
{
|
variable.CollectDeviceRunTime = device;
|
||||||
variable.CollectDeviceRunTime = device;
|
variable.DeviceName = device.Name;
|
||||||
variable.DeviceName = device.Name;
|
}
|
||||||
}
|
});
|
||||||
return Task.CompletedTask;
|
return runtime.Values.ToList();
|
||||||
});
|
|
||||||
return runtime;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -270,12 +269,11 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
runtime.PluginName = pluginName;
|
runtime.PluginName = pluginName;
|
||||||
runtime.DeviceVariableRunTimes = collectVariableRunTimes;
|
runtime.DeviceVariableRunTimes = collectVariableRunTimes;
|
||||||
|
|
||||||
await collectVariableRunTimes.ForeachAsync(variable =>
|
collectVariableRunTimes.ParallelForEach(variable =>
|
||||||
{
|
{
|
||||||
variable.CollectDeviceRunTime = runtime;
|
variable.CollectDeviceRunTime = runtime;
|
||||||
variable.DeviceName = runtime.Name;
|
variable.DeviceName = runtime.Name;
|
||||||
return Task.CompletedTask;
|
});
|
||||||
});
|
|
||||||
return new() { runtime };
|
return new() { runtime };
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -291,12 +289,13 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
devDatas ??= GetCacheList();
|
devDatas ??= GetCacheList();
|
||||||
|
|
||||||
//总数据
|
//总数据
|
||||||
Dictionary<string, object> sheets = new Dictionary<string, object>();
|
Dictionary<string, object> sheets = new();
|
||||||
//设备页
|
//设备页
|
||||||
List<Dictionary<string, object>> devExports = new();
|
List<Dictionary<string, object>> devExports = new();
|
||||||
//设备附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
//设备附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
||||||
Dictionary<string, List<Dictionary<string, object>>> devicePropertys = new();
|
Dictionary<string, List<Dictionary<string, object>>> devicePropertys = new();
|
||||||
|
var driverPluginDicts = _driverPluginService.GetCacheList().ToDictionary(a => a.Id);
|
||||||
|
var deviceDicts = devDatas.ToDictionary(a => a.Id);
|
||||||
foreach (var devData in devDatas)
|
foreach (var devData in devDatas)
|
||||||
{
|
{
|
||||||
#region 设备sheet
|
#region 设备sheet
|
||||||
@@ -310,10 +309,13 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
//数据源增加
|
//数据源增加
|
||||||
devExport.Add(desc ?? item.Name, item.GetValue(devData)?.ToString());
|
devExport.Add(desc ?? item.Name, item.GetValue(devData)?.ToString());
|
||||||
}
|
}
|
||||||
|
driverPluginDicts.TryGetValue(devData.PluginId, out var driverPlugin);
|
||||||
|
deviceDicts.TryGetValue(devData.RedundantDeviceId, out var redundantDevice);
|
||||||
|
|
||||||
//设备实体没有包含插件名称,手动插入
|
//设备实体没有包含插件名称,手动插入
|
||||||
devExport.Add(ExportHelpers.PluginName, _driverPluginService.GetNameById(devData.PluginId));
|
devExport.Add(ExportHelpers.PluginName, driverPlugin.AssembleName);
|
||||||
//设备实体没有包含冗余设备名称,手动插入
|
//设备实体没有包含冗余设备名称,手动插入
|
||||||
devExport.Add(ExportHelpers.RedundantDeviceName, GetNameById(devData.RedundantDeviceId));
|
devExport.Add(ExportHelpers.RedundantDeviceName, redundantDevice?.Name);
|
||||||
|
|
||||||
//添加完整设备信息
|
//添加完整设备信息
|
||||||
devExports.Add(devExport);
|
devExports.Add(devExport);
|
||||||
@@ -323,7 +325,7 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
#region 插件sheet
|
#region 插件sheet
|
||||||
//插件属性
|
//插件属性
|
||||||
//单个设备的行数据
|
//单个设备的行数据
|
||||||
Dictionary<string, object> driverInfo = new Dictionary<string, object>();
|
Dictionary<string, object> driverInfo = new();
|
||||||
//没有包含设备名称,手动插入
|
//没有包含设备名称,手动插入
|
||||||
if (devData.DevicePropertys.Count > 0)
|
if (devData.DevicePropertys.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -336,7 +338,7 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
}
|
}
|
||||||
|
|
||||||
//插件名称去除首部ThingsGateway.作为表名
|
//插件名称去除首部ThingsGateway.作为表名
|
||||||
var pluginName = _driverPluginService.GetNameById(devData.PluginId).Replace(ExportHelpers.PluginLeftName, "");
|
var pluginName = driverPlugin.AssembleName.Replace(ExportHelpers.PluginLeftName, "");
|
||||||
if (devicePropertys.ContainsKey(pluginName))
|
if (devicePropertys.ContainsKey(pluginName))
|
||||||
{
|
{
|
||||||
if (driverInfo.Count > 0)
|
if (driverInfo.Count > 0)
|
||||||
@@ -372,6 +374,8 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
using var stream = file.OpenReadStream(512000000);
|
using var stream = file.OpenReadStream(512000000);
|
||||||
await stream.CopyToAsync(fs);
|
await stream.CopyToAsync(fs);
|
||||||
var sheetNames = MiniExcel.GetSheetNames(fs);
|
var sheetNames = MiniExcel.GetSheetNames(fs);
|
||||||
|
var deviceDicts = GetCacheList().ToDictionary(a => a.Name);
|
||||||
|
var pluginDicts = _driverPluginService.GetCacheList().ToDictionary(a => a.AssembleName);
|
||||||
|
|
||||||
//导入检验结果
|
//导入检验结果
|
||||||
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
||||||
@@ -380,7 +384,7 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
foreach (var sheetName in sheetNames)
|
foreach (var sheetName in sheetNames)
|
||||||
{
|
{
|
||||||
//单页数据
|
//单页数据
|
||||||
var rows = (await fs.QueryAsync(useHeaderRow: true, sheetName: sheetName)).Cast<IDictionary<string, object>>();
|
var rows = fs.Query(useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
|
||||||
#region 采集设备sheet
|
#region 采集设备sheet
|
||||||
if (sheetName == ExportHelpers.CollectDeviceSheetName)
|
if (sheetName == ExportHelpers.CollectDeviceSheetName)
|
||||||
{
|
{
|
||||||
@@ -388,55 +392,57 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
ImportPreviewOutput<CollectDevice> importPreviewOutput = new();
|
ImportPreviewOutput<CollectDevice> importPreviewOutput = new();
|
||||||
ImportPreviews.Add(sheetName, importPreviewOutput);
|
ImportPreviews.Add(sheetName, importPreviewOutput);
|
||||||
deviceImportPreview = importPreviewOutput;
|
deviceImportPreview = importPreviewOutput;
|
||||||
|
List<CollectDevice> devices = new();
|
||||||
|
rows.ForEach(item =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var device = ((ExpandoObject)item).ConvertToEntity<CollectDevice>(true);
|
||||||
|
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(UploadDevice.Name), device.Name);
|
||||||
|
//var hasName = GetIdByName(device.Name) > 0;
|
||||||
|
//if (hasDup || hasName)
|
||||||
|
//{
|
||||||
|
// importPreviewOutput.HasError = true;
|
||||||
|
// importPreviewOutput.Results.Add((false, "名称重复"));
|
||||||
|
// return Task.CompletedTask;
|
||||||
|
//}
|
||||||
|
#region 特殊转化名称
|
||||||
|
//转化插件名称
|
||||||
|
var hasPlugin = item.TryGetValue(ExportHelpers.PluginName, out var pluginObj);
|
||||||
|
|
||||||
List<CollectDevice> devices = new List<CollectDevice>();
|
if (pluginObj == null || !pluginDicts.TryGetValue(pluginObj.ToString(), out var plugin))
|
||||||
await rows.ForeachAsync(item =>
|
{
|
||||||
{
|
//找不到对应的插件
|
||||||
try
|
importPreviewOutput.HasError = true;
|
||||||
{
|
importPreviewOutput.Results.Add((row++, false, $"{ExportHelpers.PluginName}不存在"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//转化冗余设备名称
|
||||||
|
var hasRedundant = item.TryGetValue(ExportHelpers.PluginName, out var redundantObj);
|
||||||
|
|
||||||
var device = ((ExpandoObject)item).ConvertToEntity<CollectDevice>(true);
|
#endregion
|
||||||
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(UploadDevice.Name), device.Name);
|
//插件ID、设备ID、冗余设备ID都需要手动补录
|
||||||
//var hasName = GetIdByName(device.Name) > 0;
|
device.PluginId = plugin.Id;
|
||||||
//if (hasDup || hasName)
|
if (hasRedundant && deviceDicts.TryGetValue(redundantObj.ToString(), out var rendundantDevice))
|
||||||
//{
|
{
|
||||||
// importPreviewOutput.HasError = true;
|
device.RedundantDeviceId = rendundantDevice.Id;
|
||||||
// importPreviewOutput.Results.Add((false, "名称重复"));
|
}
|
||||||
// return Task.CompletedTask;
|
device.Id = deviceDicts.TryGetValue(device.Name, out var collectDevice) ? collectDevice.Id : YitIdHelper.NextId();
|
||||||
//}
|
|
||||||
#region 特殊转化名称
|
|
||||||
//转化插件名称
|
|
||||||
var pluginName = item.FirstOrDefault(a => a.Key == ExportHelpers.PluginName).Value;
|
|
||||||
if (_driverPluginService.GetIdByName(pluginName?.ToString()) == null)
|
|
||||||
{
|
|
||||||
//找不到对应的插件
|
|
||||||
importPreviewOutput.HasError = true;
|
|
||||||
importPreviewOutput.Results.Add((row++, false, $"{ExportHelpers.PluginName}不存在"));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
//转化冗余设备名称
|
|
||||||
var redundantDeviceName = item.FirstOrDefault(a => a.Key == ExportHelpers.RedundantDeviceName).Value;
|
|
||||||
|
|
||||||
#endregion
|
devices.Add(device);
|
||||||
//插件ID、设备ID、冗余设备ID都需要手动补录
|
importPreviewOutput.Results.Add((row++, true, "成功"));
|
||||||
device.PluginId = _driverPluginService.GetIdByName(pluginName.ToString()).ToLong();
|
return;
|
||||||
device.RedundantDeviceId = GetIdByName(redundantDeviceName?.ToString()).ToLong();
|
}
|
||||||
device.Id = this.GetIdByName(device.Name) ?? YitIdHelper.NextId();
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
devices.Add(device);
|
importPreviewOutput.HasError = true;
|
||||||
importPreviewOutput.Results.Add((row++, true, "成功"));
|
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
||||||
return Task.CompletedTask;
|
return;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
});
|
||||||
{
|
importPreviewOutput.Data = devices.ToDictionary(a => a.Name);
|
||||||
|
|
||||||
importPreviewOutput.HasError = true;
|
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
importPreviewOutput.Data = devices;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@@ -459,49 +465,43 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
using var serviceScope = _scopeFactory.CreateScope();
|
using var serviceScope = _scopeFactory.CreateScope();
|
||||||
var pluginSingletonService = serviceScope.ServiceProvider.GetService<PluginSingletonService>();
|
var pluginSingletonService = serviceScope.ServiceProvider.GetService<PluginSingletonService>();
|
||||||
var driver = (DriverBase)pluginSingletonService.GetDriver(YitIdHelper.NextId(), driverPlugin);
|
var driver = (DriverBase)pluginSingletonService.GetDriver(YitIdHelper.NextId(), driverPlugin);
|
||||||
var propertys = driver.DriverPropertys.GetType().GetAllProps().Where(a => a.GetCustomAttribute<DevicePropertyAttribute>() != null);
|
var propertys = driver.DriverPropertys.GetType().GetAllProps()
|
||||||
await rows.ForeachAsync(item =>
|
.Where(a => a.GetCustomAttribute<DevicePropertyAttribute>() != null)
|
||||||
{
|
.ToDictionary(a => a.FindDisplayAttribute(a => a.GetCustomAttribute<DevicePropertyAttribute>()?.Description));
|
||||||
try
|
rows.ForEach(item =>
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
List<DependencyProperty> devices = new List<DependencyProperty>();
|
List<DependencyProperty> devices = new();
|
||||||
foreach (var item1 in item)
|
foreach (var keyValuePair in item)
|
||||||
{
|
{
|
||||||
var propertyInfo = propertys.FirstOrDefault(p => p.FindDisplayAttribute(a => a.GetCustomAttribute<DevicePropertyAttribute>()?.Description) == item1.Key);
|
if (propertys.TryGetValue(keyValuePair.Key, out var propertyInfo))
|
||||||
if (propertyInfo == null)
|
{
|
||||||
{
|
devices.Add(new()
|
||||||
//不存在时不报错
|
{
|
||||||
}
|
PropertyName = propertyInfo.Name,
|
||||||
else
|
Description = keyValuePair.Key.ToString(),
|
||||||
{
|
Value = keyValuePair.Value?.ToString()
|
||||||
devices.Add(new()
|
});
|
||||||
{
|
}
|
||||||
PropertyName = propertyInfo.Name,
|
|
||||||
Description = item1.Key.ToString(),
|
|
||||||
Value = item1.Value?.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//转化插件名称
|
//转化插件名称
|
||||||
var value = item.FirstOrDefault(a => a.Key == ExportHelpers.DeviceName);
|
|
||||||
if (deviceImportPreview.Data?.Any(it => it.Name == value.Value.ToString()) == true)
|
var value = item[ExportHelpers.DeviceName];
|
||||||
{
|
|
||||||
var deviceId = this.GetIdByName(value.Value.ToString()) ?? deviceImportPreview.Data.FirstOrDefault(it => it.Name == value.Value.ToString()).Id;
|
deviceImportPreview.Data[value.ToString()].DevicePropertys = devices;
|
||||||
deviceImportPreview.Data.FirstOrDefault(a => a.Id == deviceId).DevicePropertys = devices;
|
importPreviewOutput.Results.Add((row++, true, "成功"));
|
||||||
}
|
return;
|
||||||
importPreviewOutput.Data.Add(string.Empty);
|
}
|
||||||
importPreviewOutput.Results.Add((row++, true, "成功"));
|
catch (Exception ex)
|
||||||
return Task.CompletedTask;
|
{
|
||||||
}
|
importPreviewOutput.HasError = true;
|
||||||
catch (Exception ex)
|
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
||||||
{
|
return;
|
||||||
importPreviewOutput.HasError = true;
|
}
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
});
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -521,7 +521,7 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
|||||||
if (item.Key == ExportHelpers.CollectDeviceSheetName)
|
if (item.Key == ExportHelpers.CollectDeviceSheetName)
|
||||||
{
|
{
|
||||||
var collectDeviceImports = ((ImportPreviewOutput<CollectDevice>)item.Value).Data;
|
var collectDeviceImports = ((ImportPreviewOutput<CollectDevice>)item.Value).Data;
|
||||||
collectDevices = collectDeviceImports.Adapt<List<CollectDevice>>();
|
collectDevices = collectDeviceImports.Values.Adapt<List<CollectDevice>>();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,14 @@ using Microsoft.AspNetCore.Components.Forms;
|
|||||||
|
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
|
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using ThingsGateway.Core;
|
using ThingsGateway.Core;
|
||||||
using ThingsGateway.Core.Extension;
|
using ThingsGateway.Foundation.Extension.Generic;
|
||||||
|
|
||||||
namespace ThingsGateway.Web.Foundation;
|
namespace ThingsGateway.Web.Foundation;
|
||||||
|
|
||||||
@@ -162,30 +163,31 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
public List<UploadDevice> GetCacheList()
|
public List<UploadDevice> GetCacheList()
|
||||||
{
|
{
|
||||||
//先从Cache拿
|
//先从Cache拿
|
||||||
var collectDevice = _sysCacheService.Get<List<UploadDevice>>(ThingsGatewayCacheConst.Cache_UploadDevice, "");
|
var uploadDevice = _sysCacheService.Get<List<UploadDevice>>(ThingsGatewayCacheConst.Cache_UploadDevice, "");
|
||||||
if (collectDevice == null)
|
if (uploadDevice == null)
|
||||||
{
|
{
|
||||||
collectDevice = Context.Queryable<UploadDevice>().ToList();
|
uploadDevice = Context.Queryable<UploadDevice>().ToList();
|
||||||
if (collectDevice != null)
|
if (uploadDevice != null)
|
||||||
{
|
{
|
||||||
//插入Cache
|
//插入Cache
|
||||||
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_UploadDevice, "", collectDevice);
|
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_UploadDevice, "", uploadDevice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return collectDevice;
|
return uploadDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public List<UploadDeviceRunTime> GetUploadDeviceRuntime(long devId = 0)
|
public List<UploadDeviceRunTime> GetUploadDeviceRuntime(long devId = 0)
|
||||||
{
|
{
|
||||||
|
ConcurrentDictionary<long, DriverPlugin> driverPlugins = new(_driverPluginService.GetCacheList().ToDictionary(a => a.Id));
|
||||||
if (devId == 0)
|
if (devId == 0)
|
||||||
{
|
{
|
||||||
var devices = GetCacheList().Where(a => a.Enable).ToList();
|
var devices = GetCacheList().Where(a => a.Enable).ToList();
|
||||||
var runtime = devices.Adapt<List<UploadDeviceRunTime>>();
|
var runtime = devices.Adapt<List<UploadDeviceRunTime>>();
|
||||||
foreach (var device in runtime)
|
foreach (var device in runtime)
|
||||||
{
|
{
|
||||||
var pluginName = _driverPluginService.GetNameById(device.PluginId);
|
driverPlugins.TryGetValue(device.PluginId, out var driverPlugin);
|
||||||
device.PluginName = pluginName;
|
device.PluginName = driverPlugin?.AssembleName;
|
||||||
}
|
}
|
||||||
return runtime;
|
return runtime;
|
||||||
}
|
}
|
||||||
@@ -196,8 +198,8 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
var runtime = devices.Adapt<List<UploadDeviceRunTime>>();
|
var runtime = devices.Adapt<List<UploadDeviceRunTime>>();
|
||||||
foreach (var device in runtime)
|
foreach (var device in runtime)
|
||||||
{
|
{
|
||||||
var pluginName = _driverPluginService.GetNameById(device.PluginId);
|
driverPlugins.TryGetValue(device.PluginId, out var driverPlugin);
|
||||||
device.PluginName = pluginName;
|
device.PluginName = driverPlugin?.AssembleName;
|
||||||
}
|
}
|
||||||
return runtime;
|
return runtime;
|
||||||
|
|
||||||
@@ -214,7 +216,7 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
devDatas ??= GetCacheList();
|
devDatas ??= GetCacheList();
|
||||||
|
|
||||||
//总数据
|
//总数据
|
||||||
Dictionary<string, object> sheets = new Dictionary<string, object>();
|
Dictionary<string, object> sheets = new();
|
||||||
//设备页
|
//设备页
|
||||||
List<Dictionary<string, object>> devExports = new();
|
List<Dictionary<string, object>> devExports = new();
|
||||||
//设备附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
//设备附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
||||||
@@ -244,7 +246,7 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
#region 插件sheet
|
#region 插件sheet
|
||||||
//插件属性
|
//插件属性
|
||||||
//单个设备的行数据
|
//单个设备的行数据
|
||||||
Dictionary<string, object> driverInfo = new Dictionary<string, object>();
|
Dictionary<string, object> driverInfo = new();
|
||||||
//没有包含设备名称,手动插入
|
//没有包含设备名称,手动插入
|
||||||
if (devData.DevicePropertys.Count > 0)
|
if (devData.DevicePropertys.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -293,6 +295,8 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
using var stream = file.OpenReadStream(512000000);
|
using var stream = file.OpenReadStream(512000000);
|
||||||
await stream.CopyToAsync(fs);
|
await stream.CopyToAsync(fs);
|
||||||
var sheetNames = MiniExcel.GetSheetNames(fs);
|
var sheetNames = MiniExcel.GetSheetNames(fs);
|
||||||
|
var deviceDicts = GetCacheList().ToDictionary(a => a.Name);
|
||||||
|
var pluginDicts = _driverPluginService.GetCacheList().ToDictionary(a => a.AssembleName);
|
||||||
|
|
||||||
//导入检验结果
|
//导入检验结果
|
||||||
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
||||||
@@ -301,7 +305,7 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
foreach (var sheetName in sheetNames)
|
foreach (var sheetName in sheetNames)
|
||||||
{
|
{
|
||||||
//单页数据
|
//单页数据
|
||||||
var rows = (await fs.QueryAsync(useHeaderRow: true, sheetName: sheetName)).Cast<IDictionary<string, object>>();
|
var rows = (fs.Query(useHeaderRow: true, sheetName: sheetName)).Cast<IDictionary<string, object>>();
|
||||||
#region 上传设备sheet
|
#region 上传设备sheet
|
||||||
if (sheetName == ExportHelpers.UploadDeviceSheetName)
|
if (sheetName == ExportHelpers.UploadDeviceSheetName)
|
||||||
{
|
{
|
||||||
@@ -310,47 +314,48 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
ImportPreviews.Add(sheetName, importPreviewOutput);
|
ImportPreviews.Add(sheetName, importPreviewOutput);
|
||||||
deviceImportPreview = importPreviewOutput;
|
deviceImportPreview = importPreviewOutput;
|
||||||
|
|
||||||
List<UploadDevice> devices = new List<UploadDevice>();
|
List<UploadDevice> devices = new();
|
||||||
await rows.ForeachAsync(item =>
|
rows.ForEach(item =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var device = ((ExpandoObject)item).ConvertToEntity<UploadDevice>(true);
|
var device = ((ExpandoObject)item).ConvertToEntity<UploadDevice>(true);
|
||||||
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(UploadDevice.Name), device.Name);
|
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(UploadDevice.Name), device.Name);
|
||||||
//var hasName = GetIdByName(device.Name) > 0;
|
//var hasName = GetIdByName(device.Name) > 0;
|
||||||
//if (hasDup || hasName)
|
//if (hasDup || hasName)
|
||||||
//{
|
//{
|
||||||
// importPreviewOutput.HasError = true;
|
// importPreviewOutput.HasError = true;
|
||||||
// importPreviewOutput.Results.Add((false, "名称重复"));
|
// importPreviewOutput.Results.Add((false, "名称重复"));
|
||||||
// return Task.CompletedTask;
|
// return Task.CompletedTask;
|
||||||
//}
|
//}
|
||||||
#region 特殊转化名称
|
#region 特殊转化名称
|
||||||
//转化插件名称
|
//转化插件名称
|
||||||
var pluginName = item.FirstOrDefault(a => a.Key == ExportHelpers.PluginName).Value;
|
var hasPlugin = item.TryGetValue(ExportHelpers.PluginName, out var pluginObj);
|
||||||
if (_driverPluginService.GetIdByName(pluginName?.ToString()) == null)
|
|
||||||
{
|
|
||||||
//找不到对应的插件
|
|
||||||
importPreviewOutput.HasError = true;
|
|
||||||
importPreviewOutput.Results.Add((row++, false, $"{ExportHelpers.PluginName}不存在"));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
//插件ID、设备ID都需要手动补录
|
|
||||||
device.PluginId = _driverPluginService.GetIdByName(pluginName?.ToString()).ToLong();
|
|
||||||
device.Id = this.GetIdByName(device.Name) ?? YitIdHelper.NextId();
|
|
||||||
|
|
||||||
devices.Add(device);
|
if (pluginObj == null || !pluginDicts.TryGetValue(pluginObj.ToString(), out var plugin))
|
||||||
importPreviewOutput.Results.Add((row++, true, "成功"));
|
{
|
||||||
return Task.CompletedTask;
|
//找不到对应的插件
|
||||||
}
|
importPreviewOutput.HasError = true;
|
||||||
catch (Exception ex)
|
importPreviewOutput.Results.Add((row++, false, $"{ExportHelpers.PluginName}不存在"));
|
||||||
{
|
return;
|
||||||
importPreviewOutput.HasError = true;
|
}
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
#endregion
|
||||||
return Task.CompletedTask;
|
//插件ID、设备ID都需要手动补录
|
||||||
}
|
device.PluginId = plugin.Id;
|
||||||
});
|
device.Id = deviceDicts.TryGetValue(device.Name, out var uploadDevice) ? uploadDevice.Id : YitIdHelper.NextId();
|
||||||
importPreviewOutput.Data = devices;
|
|
||||||
|
devices.Add(device);
|
||||||
|
importPreviewOutput.Results.Add((row++, true, "成功"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
importPreviewOutput.Data = devices.ToDictionary(a => a.Name);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@@ -374,51 +379,43 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
using var serviceScope = _scopeFactory.CreateScope();
|
using var serviceScope = _scopeFactory.CreateScope();
|
||||||
var pluginSingletonService = serviceScope.ServiceProvider.GetService<PluginSingletonService>();
|
var pluginSingletonService = serviceScope.ServiceProvider.GetService<PluginSingletonService>();
|
||||||
var driver = (DriverBase)pluginSingletonService.GetDriver(YitIdHelper.NextId(), driverPlugin);
|
var driver = (DriverBase)pluginSingletonService.GetDriver(YitIdHelper.NextId(), driverPlugin);
|
||||||
var propertys = driver.DriverPropertys.GetType().GetAllProps().Where(a => a.GetCustomAttribute<DevicePropertyAttribute>() != null);
|
var propertys = driver.DriverPropertys.GetType().GetAllProps()
|
||||||
await rows.ForeachAsync(item =>
|
.Where(a => a.GetCustomAttribute<DevicePropertyAttribute>() != null)
|
||||||
{
|
.ToDictionary(a => a.FindDisplayAttribute(a => a.GetCustomAttribute<DevicePropertyAttribute>()?.Description));
|
||||||
try
|
rows.ForEach(item =>
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
|
||||||
List<DependencyProperty> devices = new List<DependencyProperty>();
|
|
||||||
foreach (var item1 in item)
|
|
||||||
{
|
{
|
||||||
var propertyInfo = propertys.FirstOrDefault(p => p.FindDisplayAttribute(a => a.GetCustomAttribute<DevicePropertyAttribute>()?.Description) == item1.Key);
|
|
||||||
if (propertyInfo == null)
|
|
||||||
|
List<DependencyProperty> devices = new();
|
||||||
|
foreach (var keyValuePair in item)
|
||||||
{
|
{
|
||||||
//不存在时不报错
|
if (propertys.TryGetValue(keyValuePair.Key, out var propertyInfo))
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
devices.Add(new()
|
|
||||||
{
|
{
|
||||||
PropertyName = propertyInfo.Name,
|
devices.Add(new()
|
||||||
Description = item1.Key.ToString(),
|
{
|
||||||
Value = item1.Value?.ToString()
|
PropertyName = propertyInfo.Name,
|
||||||
});
|
Description = keyValuePair.Key.ToString(),
|
||||||
|
Value = keyValuePair.Value?.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//转化设备名称
|
||||||
|
var value = item[ExportHelpers.DeviceName];
|
||||||
|
|
||||||
|
deviceImportPreview.Data[value.ToString()].DevicePropertys = devices;
|
||||||
|
importPreviewOutput.Results.Add((row++, true, "成功"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
//转化设备名称
|
catch (Exception ex)
|
||||||
var deviceName = item.FirstOrDefault(a => a.Key == ExportHelpers.DeviceName).Value;
|
|
||||||
if (deviceImportPreview.Data?.Any(it => it.Name == deviceName.ToString()) == true)
|
|
||||||
{
|
{
|
||||||
var deviceId = this.GetIdByName(deviceName.ToString()) ?? deviceImportPreview.Data.FirstOrDefault(it => it.Name == deviceName.ToString()).Id;
|
importPreviewOutput.HasError = true;
|
||||||
deviceImportPreview.Data.FirstOrDefault(a => a.Id == deviceId).DevicePropertys = devices;
|
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
importPreviewOutput.Data.Add(string.Empty);
|
});
|
||||||
importPreviewOutput.Results.Add((row++, true, "成功"));
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
importPreviewOutput.HasError = true;
|
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,18 +429,18 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
|||||||
[OperDesc("导入上传设备表", IsRecordPar = false)]
|
[OperDesc("导入上传设备表", IsRecordPar = false)]
|
||||||
public async Task ImportAsync(Dictionary<string, ImportPreviewOutputBase> input)
|
public async Task ImportAsync(Dictionary<string, ImportPreviewOutputBase> input)
|
||||||
{
|
{
|
||||||
var collectDevices = new List<UploadDevice>();
|
var uploadDevices = new List<UploadDevice>();
|
||||||
foreach (var item in input)
|
foreach (var item in input)
|
||||||
{
|
{
|
||||||
if (item.Key == ExportHelpers.UploadDeviceSheetName)
|
if (item.Key == ExportHelpers.UploadDeviceSheetName)
|
||||||
{
|
{
|
||||||
var collectDeviceImports = ((ImportPreviewOutput<UploadDevice>)item.Value).Data;
|
var uploadDeviceImports = ((ImportPreviewOutput<UploadDevice>)item.Value).Data;
|
||||||
collectDevices = collectDeviceImports.Adapt<List<UploadDevice>>();
|
uploadDevices = uploadDeviceImports.Values.Adapt<List<UploadDevice>>();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Context.Storageable(collectDevices).ExecuteCommandAsync();
|
await Context.Storageable(uploadDevices).ExecuteCommandAsync();
|
||||||
_sysCacheService.Remove(ThingsGatewayCacheConst.Cache_CollectDevice, "");//cache删除
|
_sysCacheService.Remove(ThingsGatewayCacheConst.Cache_UploadDevice, "");//cache删除
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public interface IVariableService : ITransient
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据名称获取ID
|
/// 根据名称获取ID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
long GetIdByName(string name, bool onlyCache = true);
|
long GetIdByName(string name);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取中间变量运行态
|
/// 获取中间变量运行态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -80,7 +80,7 @@ public interface IVariableService : ITransient
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据ID获取名称
|
/// 根据ID获取名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string GetNameById(long id, bool onlyCache = true);
|
string GetNameById(long id);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 导入
|
/// 导入
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -18,13 +18,14 @@ using Microsoft.AspNetCore.Components.Forms;
|
|||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
using MiniExcelLibs.OpenXml;
|
using MiniExcelLibs.OpenXml;
|
||||||
|
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
using ThingsGateway.Core;
|
using ThingsGateway.Core;
|
||||||
using ThingsGateway.Core.Extension;
|
|
||||||
|
|
||||||
using TouchSocket.Core;
|
using TouchSocket.Core;
|
||||||
|
|
||||||
@@ -66,11 +67,11 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public long GetIdByName(string name, bool onlyCache = false)
|
public long GetIdByName(string name)
|
||||||
{
|
{
|
||||||
//先从Cache拿
|
//先从Cache拿
|
||||||
var id = _sysCacheService.Get<long>(ThingsGatewayCacheConst.Cache_DeviceVariableName, name);
|
var id = _sysCacheService.Get<long>(ThingsGatewayCacheConst.Cache_DeviceVariableName, name);
|
||||||
if (id == 0 && !onlyCache)
|
if (id == 0)
|
||||||
{
|
{
|
||||||
//单查获取对应ID
|
//单查获取对应ID
|
||||||
id = Context.Queryable<DeviceVariable>().Where(it => it.Name == name).Select(it => it.Id).First();
|
id = Context.Queryable<DeviceVariable>().Where(it => it.Name == name).Select(it => it.Id).First();
|
||||||
@@ -83,11 +84,11 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string GetNameById(long Id, bool onlyCache = true)
|
public string GetNameById(long Id)
|
||||||
{
|
{
|
||||||
//先从Cache拿
|
//先从Cache拿
|
||||||
var name = _sysCacheService.Get<string>(ThingsGatewayCacheConst.Cache_DeviceVariableId, Id.ToString());
|
var name = _sysCacheService.Get<string>(ThingsGatewayCacheConst.Cache_DeviceVariableId, Id.ToString());
|
||||||
if (name.IsNullOrEmpty() && !onlyCache)
|
if (name.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
//单查获取用户账号对应ID
|
//单查获取用户账号对应ID
|
||||||
name = Context.Queryable<DeviceVariable>().Where(it => it.Id == Id).Select(it => it.Name).First();
|
name = Context.Queryable<DeviceVariable>().Where(it => it.Id == Id).Select(it => it.Name).First();
|
||||||
@@ -287,41 +288,77 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
[OperDesc("导出变量表", IsRecordPar = false)]
|
[OperDesc("导出变量表", IsRecordPar = false)]
|
||||||
public async Task<MemoryStream> MemoryVariableExportFileAsync(List<MemoryVariable> devDatas = null)
|
public async Task<MemoryStream> MemoryVariableExportFileAsync(List<MemoryVariable> deviceVariables = null)
|
||||||
{
|
{
|
||||||
devDatas ??= (await GetListAsync(a => a.IsMemoryVariable == true)).Adapt<List<MemoryVariable>>();
|
deviceVariables ??= (await GetListAsync(a => a.IsMemoryVariable == true)).Adapt<List<MemoryVariable>>();
|
||||||
|
|
||||||
//总数据
|
//总数据
|
||||||
Dictionary<string, object> sheets = new Dictionary<string, object>();
|
Dictionary<string, object> sheets = new Dictionary<string, object>();
|
||||||
//变量页
|
//变量页
|
||||||
List<Dictionary<string, object>> devExports = new();
|
ConcurrentList<Dictionary<string, object>> devExports = new();
|
||||||
//变量附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
//变量附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
||||||
Dictionary<string, List<Dictionary<string, object>>> devicePropertys = new();
|
ConcurrentDictionary<string, List<Dictionary<string, object>>> devicePropertys = new();
|
||||||
await devDatas.ForeachAsync(devData =>
|
var upDeviceDicts = _uploadDeviceService.GetCacheList().ToDictionary(a => a.Id);
|
||||||
|
var collectDeviceDicts = _collectDeviceService.GetCacheList().ToDictionary(a => a.Id);
|
||||||
|
var driverPluginDicts = _driverPluginService.GetCacheList().ToDictionary(a => a.Id);
|
||||||
|
deviceVariables.ParallelForEach(devData =>
|
||||||
{
|
{
|
||||||
#region 变量sheet
|
#region 变量sheet
|
||||||
//变量页
|
//变量页
|
||||||
var data = devData.GetType().GetAllProps().Where(a => a.GetCustomAttribute<ExcelAttribute>() != null);
|
var data = devData.GetType().GetAllProps().Where(a => a.GetCustomAttribute<ExcelAttribute>() != null);
|
||||||
Dictionary<string, object> devExport = new();
|
Dictionary<string, object> variableExport = new();
|
||||||
|
|
||||||
foreach (var item in data)
|
foreach (var item in data)
|
||||||
{
|
{
|
||||||
//描述
|
//描述
|
||||||
var desc = ObjectExtensions.FindDisplayAttribute(item);
|
var desc = ObjectExtensions.FindDisplayAttribute(item);
|
||||||
//数据源增加
|
//数据源增加
|
||||||
devExport.Add(desc ?? item.Name, item.GetValue(devData)?.ToString());
|
variableExport.Add(desc ?? item.Name, item.GetValue(devData)?.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//添加完整变量信息
|
//添加完整变量信息
|
||||||
devExports.Add(devExport);
|
devExports.Add(variableExport);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
#region 上传插件属性
|
||||||
|
foreach (var item in devData.VariablePropertys ?? new())
|
||||||
|
{
|
||||||
|
//插件属性
|
||||||
|
//单个设备的行数据
|
||||||
|
Dictionary<string, object> driverInfo = new Dictionary<string, object>();
|
||||||
|
var has = upDeviceDicts.TryGetValue(item.Key, out var uploadDevice);
|
||||||
|
if (!has)
|
||||||
|
continue;
|
||||||
|
driverInfo.Add(ExportHelpers.UploadDeviceSheetName, uploadDevice?.Name);
|
||||||
|
//没有包含变量名称,手动插入
|
||||||
|
driverInfo.Add(ExportHelpers.DeviceVariableSheetName, devData.Name);
|
||||||
|
foreach (var item1 in item.Value)
|
||||||
|
{
|
||||||
|
//添加对应属性数据
|
||||||
|
driverInfo.Add(item1.Description, item1.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uploadDevice != null)
|
||||||
|
{
|
||||||
|
//插件名称去除首部ThingsGateway.作为表名
|
||||||
|
var pluginName = driverPluginDicts[uploadDevice.PluginId].AssembleName.Replace(ExportHelpers.PluginLeftName, "");
|
||||||
|
if (devicePropertys.ContainsKey(pluginName))
|
||||||
|
{
|
||||||
|
devicePropertys[pluginName].Add(driverInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
devicePropertys.TryAdd(pluginName, new() { driverInfo });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//添加设备页
|
//添加变量页
|
||||||
sheets.Add(ExportHelpers.DeviceVariableSheetName, devExports);
|
sheets.Add(ExportHelpers.DeviceVariableSheetName, devExports);
|
||||||
//添加插件属性页
|
//添加插件属性页
|
||||||
foreach (var item in devicePropertys)
|
foreach (var item in devicePropertys)
|
||||||
@@ -336,76 +373,79 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
[OperDesc("导出变量表", IsRecordPar = false)]
|
[OperDesc("导出变量表", IsRecordPar = false)]
|
||||||
public async Task<MemoryStream> ExportFileAsync(List<DeviceVariable> devDatas = null)
|
public async Task<MemoryStream> ExportFileAsync(List<DeviceVariable> deviceVariables = null)
|
||||||
{
|
{
|
||||||
devDatas ??= await GetListAsync(a => a.IsMemoryVariable != true || a.IsMemoryVariable == null);
|
deviceVariables ??= await GetListAsync(a => a.IsMemoryVariable != true || a.IsMemoryVariable == null);
|
||||||
|
|
||||||
//总数据
|
//总数据
|
||||||
Dictionary<string, object> sheets = new Dictionary<string, object>();
|
Dictionary<string, object> sheets = new Dictionary<string, object>();
|
||||||
//变量页
|
//变量页
|
||||||
List<Dictionary<string, object>> devExports = new();
|
ConcurrentList<Dictionary<string, object>> devExports = new();
|
||||||
//变量附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
//变量附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
|
||||||
Dictionary<string, List<Dictionary<string, object>>> devicePropertys = new();
|
ConcurrentDictionary<string, List<Dictionary<string, object>>> devicePropertys = new();
|
||||||
await devDatas.ForeachAsync(devData =>
|
var upDeviceDicts = _uploadDeviceService.GetCacheList().ToDictionary(a => a.Id);
|
||||||
{
|
var collectDeviceDicts = _collectDeviceService.GetCacheList().ToDictionary(a => a.Id);
|
||||||
#region 变量sheet
|
var driverPluginDicts = _driverPluginService.GetCacheList().ToDictionary(a => a.Id);
|
||||||
//变量页
|
deviceVariables.ParallelForEach(devData =>
|
||||||
var data = devData.GetType().GetAllProps().Where(a => a.GetCustomAttribute<ExcelAttribute>() != null);
|
{
|
||||||
Dictionary<string, object> devExport = new();
|
#region 变量sheet
|
||||||
//变量实体没有包含设备名称,手动插入
|
//变量页
|
||||||
devExport.Add(ExportHelpers.DeviceName, _collectDeviceService.GetNameById(devData.DeviceId));
|
var data = devData.GetType().GetAllProps().Where(a => a.GetCustomAttribute<ExcelAttribute>() != null);
|
||||||
|
Dictionary<string, object> variableExport = new();
|
||||||
|
//变量实体没有包含设备名称,手动插入
|
||||||
|
variableExport.Add(ExportHelpers.DeviceName, collectDeviceDicts[devData.DeviceId]);
|
||||||
|
|
||||||
foreach (var item in data)
|
foreach (var item in data)
|
||||||
{
|
{
|
||||||
//描述
|
//描述
|
||||||
var desc = ObjectExtensions.FindDisplayAttribute(item);
|
var desc = ObjectExtensions.FindDisplayAttribute(item);
|
||||||
//数据源增加
|
//数据源增加
|
||||||
devExport.Add(desc ?? item.Name, item.GetValue(devData)?.ToString());
|
variableExport.Add(desc ?? item.Name, item.GetValue(devData)?.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//添加完整变量信息
|
||||||
|
devExports.Add(variableExport);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
#region 上传插件属性
|
||||||
|
foreach (var item in devData.VariablePropertys ?? new())
|
||||||
|
{
|
||||||
|
//插件属性
|
||||||
|
//单个设备的行数据
|
||||||
|
Dictionary<string, object> driverInfo = new Dictionary<string, object>();
|
||||||
|
var has = upDeviceDicts.TryGetValue(item.Key, out var uploadDevice);
|
||||||
|
if (!has)
|
||||||
|
continue;
|
||||||
|
driverInfo.Add(ExportHelpers.UploadDeviceSheetName, uploadDevice?.Name);
|
||||||
|
//没有包含变量名称,手动插入
|
||||||
|
driverInfo.Add(ExportHelpers.DeviceVariableSheetName, devData.Name);
|
||||||
|
foreach (var item1 in item.Value)
|
||||||
|
{
|
||||||
|
//添加对应属性数据
|
||||||
|
driverInfo.Add(item1.Description, item1.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uploadDevice != null)
|
||||||
|
{
|
||||||
|
//插件名称去除首部ThingsGateway.作为表名
|
||||||
|
var pluginName = driverPluginDicts[uploadDevice.PluginId].AssembleName.Replace(ExportHelpers.PluginLeftName, "");
|
||||||
|
if (devicePropertys.ContainsKey(pluginName))
|
||||||
|
{
|
||||||
|
devicePropertys[pluginName].Add(driverInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
devicePropertys.TryAdd(pluginName, new() { driverInfo });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//添加完整变量信息
|
}
|
||||||
devExports.Add(devExport);
|
#endregion
|
||||||
|
|
||||||
#endregion
|
});
|
||||||
#region 上传插件属性
|
|
||||||
foreach (var item in devData.VariablePropertys ?? new())
|
|
||||||
{
|
|
||||||
//插件属性
|
|
||||||
//单个设备的行数据
|
|
||||||
Dictionary<string, object> driverInfo = new Dictionary<string, object>();
|
|
||||||
var uploadDevice = _uploadDeviceService.GetDeviceById(item.Key);
|
|
||||||
driverInfo.Add(ExportHelpers.UploadDeviceSheetName, uploadDevice?.Name);
|
|
||||||
//没有包含变量名称,手动插入
|
|
||||||
driverInfo.Add(ExportHelpers.DeviceVariableSheetName, devData.Name);
|
|
||||||
foreach (var item1 in item.Value)
|
|
||||||
{
|
|
||||||
//添加对应属性数据
|
|
||||||
driverInfo.Add(item1.Description, item1.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uploadDevice != null)
|
//添加变量页
|
||||||
{
|
|
||||||
//插件名称去除首部ThingsGateway.作为表名
|
|
||||||
var pluginName = _driverPluginService.GetNameById(uploadDevice.PluginId).Replace(ExportHelpers.PluginLeftName, "");
|
|
||||||
if (devicePropertys.ContainsKey(pluginName))
|
|
||||||
{
|
|
||||||
devicePropertys[pluginName].Add(driverInfo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
devicePropertys.Add(pluginName, new() { driverInfo });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
});
|
|
||||||
|
|
||||||
//添加设备页
|
|
||||||
sheets.Add(ExportHelpers.DeviceVariableSheetName, devExports);
|
sheets.Add(ExportHelpers.DeviceVariableSheetName, devExports);
|
||||||
//添加插件属性页
|
//添加插件属性页
|
||||||
foreach (var item in devicePropertys)
|
foreach (var item in devicePropertys)
|
||||||
@@ -427,13 +467,14 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
await stream.CopyToAsync(fs);
|
await stream.CopyToAsync(fs);
|
||||||
var sheetNames = MiniExcel.GetSheetNames(fs);
|
var sheetNames = MiniExcel.GetSheetNames(fs);
|
||||||
|
|
||||||
var deviceVariables = await GetListAsync();
|
var dbVariables = await Context.Queryable<DeviceVariable>().Select(it => new { it.Id, it.Name }).ToListAsync();
|
||||||
foreach (var item in deviceVariables)
|
foreach (var item in dbVariables)
|
||||||
{
|
{
|
||||||
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableName, item.Name, item.Id);
|
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableName, item.Name, item.Id);
|
||||||
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableId, item.Id.ToString(), item.Name);
|
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableId, item.Id.ToString(), item.Name);
|
||||||
}
|
}
|
||||||
|
//转为字典,提高查找效率
|
||||||
|
var dbVariableDicts = dbVariables.ToDictionary(a => a.Name);
|
||||||
//导入检验结果
|
//导入检验结果
|
||||||
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
||||||
//设备页
|
//设备页
|
||||||
@@ -451,125 +492,35 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
ImportPreviews.Add(sheetName, importPreviewOutput);
|
ImportPreviews.Add(sheetName, importPreviewOutput);
|
||||||
deviceImportPreview = importPreviewOutput;
|
deviceImportPreview = importPreviewOutput;
|
||||||
|
|
||||||
|
//线程安全
|
||||||
|
List<DeviceVariable> variables = new List<DeviceVariable>();
|
||||||
|
rows.ParallelForEach(item =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var variable = ((ExpandoObject)item).ConvertToEntity<DeviceVariable>(true);
|
||||||
|
|
||||||
List<DeviceVariable> devices = new List<DeviceVariable>();
|
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(DeviceVariable.Name), device.Name);
|
||||||
await rows.ForeachAsync(item =>
|
//var hasName = GetIdByName(device.Name) > 0;
|
||||||
{
|
//if (hasDup || hasName)
|
||||||
try
|
//{
|
||||||
{
|
// importPreviewOutput.HasError = true;
|
||||||
var device = ((ExpandoObject)item).ConvertToEntity<DeviceVariable>(true);
|
// importPreviewOutput.Results.Add((false, "名称重复"));
|
||||||
|
// return Task.CompletedTask;
|
||||||
|
//}
|
||||||
|
//变量ID都需要手动补录
|
||||||
|
variables.Add(variable);
|
||||||
|
variable.Id = dbVariableDicts.TryGetValue(variable.Name, out var dbvar1) ? dbvar1.Id : YitIdHelper.NextId();
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, "成功"));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, ex.Message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(DeviceVariable.Name), device.Name);
|
importPreviewOutput.Data = variables.OrderBy(a => a.Id).ToDictionary(a => a.Name);
|
||||||
//var hasName = GetIdByName(device.Name) > 0;
|
|
||||||
//if (hasDup || hasName)
|
|
||||||
//{
|
|
||||||
// importPreviewOutput.HasError = true;
|
|
||||||
// importPreviewOutput.Results.Add((false, "名称重复"));
|
|
||||||
// return Task.CompletedTask;
|
|
||||||
//}
|
|
||||||
//变量ID都需要手动补录
|
|
||||||
devices.Add(device);
|
|
||||||
device.Id = this.GetIdByName(device.Name, true) == 0 ? YitIdHelper.NextId() : this.GetIdByName(device.Name, true);
|
|
||||||
importPreviewOutput.Results.Add((row++, true, "成功"));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
importPreviewOutput.HasError = true;
|
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
importPreviewOutput.Data = devices;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return ImportPreviews;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile file)
|
|
||||||
{
|
|
||||||
_fileService.ImportVerification(file);
|
|
||||||
using var fs = new MemoryStream();
|
|
||||||
using var stream = file.OpenReadStream(512000000);
|
|
||||||
await stream.CopyToAsync(fs);
|
|
||||||
var sheetNames = MiniExcel.GetSheetNames(fs);
|
|
||||||
|
|
||||||
var deviceVariables = await GetListAsync();
|
|
||||||
foreach (var item in deviceVariables)
|
|
||||||
{
|
|
||||||
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableName, item.Name, item.Id);
|
|
||||||
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableId, item.Id.ToString(), item.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//导入检验结果
|
|
||||||
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
|
||||||
//设备页
|
|
||||||
ImportPreviewOutput<DeviceVariable> deviceImportPreview = new();
|
|
||||||
foreach (var sheetName in sheetNames)
|
|
||||||
{
|
|
||||||
//单页数据
|
|
||||||
var rows = fs.Query(useHeaderRow: true, sheetName: sheetName, configuration: new OpenXmlConfiguration { EnableSharedStringCache = false })
|
|
||||||
.Cast<IDictionary<string, object>>();
|
|
||||||
|
|
||||||
if (sheetName == ExportHelpers.DeviceVariableSheetName)
|
|
||||||
{
|
|
||||||
int row = 1;
|
|
||||||
ImportPreviewOutput<DeviceVariable> importPreviewOutput = new();
|
|
||||||
ImportPreviews.Add(sheetName, importPreviewOutput);
|
|
||||||
deviceImportPreview = importPreviewOutput;
|
|
||||||
|
|
||||||
|
|
||||||
List<DeviceVariable> devices = new List<DeviceVariable>();
|
|
||||||
await rows.ForeachAsync(item =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var device = ((ExpandoObject)item).ConvertToEntity<DeviceVariable>(true);
|
|
||||||
|
|
||||||
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(DeviceVariable.Name), device.Name);
|
|
||||||
//var hasName = GetIdByName(device.Name) > 0;
|
|
||||||
//if (hasDup || hasName)
|
|
||||||
//{
|
|
||||||
// importPreviewOutput.HasError = true;
|
|
||||||
// importPreviewOutput.Results.Add((false, "名称重复"));
|
|
||||||
// return Task.CompletedTask;
|
|
||||||
//}
|
|
||||||
//转化设备名称
|
|
||||||
var deviceName = item.FirstOrDefault(a => a.Key == ExportHelpers.DeviceName).Value;
|
|
||||||
if (_collectDeviceService.GetIdByName(deviceName?.ToString()) == null)
|
|
||||||
{
|
|
||||||
//找不到对应的设备
|
|
||||||
importPreviewOutput.HasError = true;
|
|
||||||
importPreviewOutput.Results.Add((row++, false, $"{deviceName}设备不存在"));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//变量ID和设备ID都需要手动补录
|
|
||||||
device.DeviceId = _collectDeviceService.GetIdByName(deviceName.ToString()).ToLong();
|
|
||||||
device.Id = this.GetIdByName(device.Name, true) == 0 ? YitIdHelper.NextId() : this.GetIdByName(device.Name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
devices.Add(device);
|
|
||||||
importPreviewOutput.Results.Add((row++, true, "成功"));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
importPreviewOutput.HasError = true;
|
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
importPreviewOutput.Data = devices;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -587,7 +538,7 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
if (pluginId == null)
|
if (pluginId == null)
|
||||||
{
|
{
|
||||||
importPreviewOutput.HasError = true;
|
importPreviewOutput.HasError = true;
|
||||||
importPreviewOutput.Results.Add((row++, false, $"插件{newName}不存在"));
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, $"插件{newName}不存在"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,59 +546,255 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
using var serviceScope = _scopeFactory.CreateScope();
|
using var serviceScope = _scopeFactory.CreateScope();
|
||||||
var pluginSingletonService = serviceScope.ServiceProvider.GetService<PluginSingletonService>();
|
var pluginSingletonService = serviceScope.ServiceProvider.GetService<PluginSingletonService>();
|
||||||
var driver = (UpLoadBase)pluginSingletonService.GetDriver(YitIdHelper.NextId(), driverPlugin);
|
var driver = (UpLoadBase)pluginSingletonService.GetDriver(YitIdHelper.NextId(), driverPlugin);
|
||||||
var propertys = driver.VariablePropertys.GetType().GetAllProps().Where(a => a.GetCustomAttribute<VariablePropertyAttribute>() != null);
|
var propertys = driver.VariablePropertys.GetType().GetAllProps()
|
||||||
await rows.ForeachAsync(item =>
|
.Where(a => a.GetCustomAttribute<VariablePropertyAttribute>() != null)
|
||||||
{
|
.ToDictionary(a => a.FindDisplayAttribute(a => a.GetCustomAttribute<VariablePropertyAttribute>()?.Description));
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
List<DependencyProperty> devices = new List<DependencyProperty>();
|
var cacheUpdeviceDicts = _uploadDeviceService.GetCacheList().ToDictionary(a => a.Name);
|
||||||
foreach (var item1 in item)
|
rows.ParallelForEach(item =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
List<DependencyProperty> dependencyProperties = new List<DependencyProperty>();
|
||||||
|
foreach (var keyValuePair in item)
|
||||||
|
{
|
||||||
|
if (propertys.TryGetValue(keyValuePair.Key, out var propertyInfo))
|
||||||
{
|
{
|
||||||
var propertyInfo = propertys.FirstOrDefault(p => p.FindDisplayAttribute(a => a.GetCustomAttribute<VariablePropertyAttribute>()?.Description) == item1.Key);
|
dependencyProperties.Add(new()
|
||||||
if (propertyInfo == null)
|
|
||||||
{
|
{
|
||||||
//不存在时不报错
|
PropertyName = propertyInfo.Name,
|
||||||
|
Description = keyValuePair.Key.ToString(),
|
||||||
|
Value = keyValuePair.Value?.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//转化插件名称
|
||||||
|
item.TryGetValue(ExportHelpers.DeviceVariableSheetName, out var variableNameObj);
|
||||||
|
item.TryGetValue(ExportHelpers.UploadDeviceSheetName, out var uploadDevName);
|
||||||
|
var variableName = variableNameObj?.ToString();
|
||||||
|
|
||||||
|
if (uploadDevName != null)
|
||||||
|
{
|
||||||
|
cacheUpdeviceDicts.TryGetValue(uploadDevName.ToString(), out var uploadDevice);
|
||||||
|
|
||||||
|
var has = deviceImportPreview.Data.TryGetValue(variableName, out var deviceVariable);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
if (uploadDevice != null)
|
||||||
|
{
|
||||||
|
deviceVariable.VariablePropertys?.AddOrUpdate(uploadDevice.Id, a => dependencyProperties, (a, b) => dependencyProperties);
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, "成功"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
devices.Add(new()
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, $"上传设备{uploadDevName}不存在"));
|
||||||
{
|
|
||||||
PropertyName = propertyInfo.Name,
|
|
||||||
Description = item1.Key.ToString(),
|
|
||||||
Value = item1.Value?.ToString()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//转化插件名称
|
else
|
||||||
var variableName = item.FirstOrDefault(a => a.Key == ExportHelpers.DeviceVariableSheetName).Value?.ToString();
|
|
||||||
var uploadDevName = item.FirstOrDefault(a => a.Key == ExportHelpers.UploadDeviceSheetName).Value?.ToString();
|
|
||||||
|
|
||||||
var uploadDevice = _uploadDeviceService.GetCacheList().FirstOrDefault(a => a.Name == uploadDevName);
|
|
||||||
|
|
||||||
if (deviceImportPreview.Data?.Any(it => it.Name == variableName) == true && uploadDevice != null)
|
|
||||||
{
|
{
|
||||||
var id = this.GetIdByName(variableName, true);
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, $"上传设备{uploadDevName}不存在"));
|
||||||
var deviceId = id != 0 ? id : deviceImportPreview.Data.FirstOrDefault(it => it.Name == variableName).Id;
|
|
||||||
deviceImportPreview?.Data?.FirstOrDefault(a => a.Id == deviceId)?.VariablePropertys?.AddOrUpdate(uploadDevice.Id, devices);
|
|
||||||
}
|
}
|
||||||
importPreviewOutput.Data.Add(string.Empty);
|
|
||||||
importPreviewOutput.Results.Add((row++, true, "成功"));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
else
|
||||||
{
|
{
|
||||||
importPreviewOutput.HasError = true;
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, $"上传设备{uploadDevName}不存在"));
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, ex.Message));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
importPreviewOutput.HasError = true;
|
importPreviewOutput.HasError = true;
|
||||||
importPreviewOutput.Results.Add((row++, false, ex.Message));
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, ex.Message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return ImportPreviews;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile file)
|
||||||
|
{
|
||||||
|
_fileService.ImportVerification(file);
|
||||||
|
using var fs = new MemoryStream();
|
||||||
|
using var stream = file.OpenReadStream(512000000);
|
||||||
|
await stream.CopyToAsync(fs);
|
||||||
|
var sheetNames = MiniExcel.GetSheetNames(fs);
|
||||||
|
|
||||||
|
var dbVariables = await Context.Queryable<DeviceVariable>().Select(it => new { it.Id, it.Name }).ToListAsync();
|
||||||
|
foreach (var item in dbVariables)
|
||||||
|
{
|
||||||
|
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableName, item.Name, item.Id);
|
||||||
|
_sysCacheService.Set(ThingsGatewayCacheConst.Cache_DeviceVariableId, item.Id.ToString(), item.Name);
|
||||||
|
}
|
||||||
|
//转为字典,提高查找效率
|
||||||
|
var dbVariableDicts = dbVariables.ToDictionary(a => a.Name);
|
||||||
|
//检验结果
|
||||||
|
Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
|
||||||
|
//设备页
|
||||||
|
ImportPreviewOutput<DeviceVariable> deviceImportPreview = new();
|
||||||
|
foreach (var sheetName in sheetNames)
|
||||||
|
{
|
||||||
|
//单页数据
|
||||||
|
var rows = fs.Query(useHeaderRow: true, sheetName: sheetName, configuration: new OpenXmlConfiguration { EnableSharedStringCache = false })
|
||||||
|
.Cast<IDictionary<string, object>>();
|
||||||
|
|
||||||
|
if (sheetName == ExportHelpers.DeviceVariableSheetName)
|
||||||
|
{
|
||||||
|
int row = 0;
|
||||||
|
ImportPreviewOutput<DeviceVariable> importPreviewOutput = new();
|
||||||
|
ImportPreviews.Add(sheetName, importPreviewOutput);
|
||||||
|
deviceImportPreview = importPreviewOutput;
|
||||||
|
var cacheDeviceDicts = _collectDeviceService.GetCacheList().ToDictionary(a => a.Name);
|
||||||
|
//线程安全
|
||||||
|
var variables = new ConcurrentList<DeviceVariable>();
|
||||||
|
//并行注意线程安全
|
||||||
|
rows.ParallelForEach(item =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var variable = ((ExpandoObject)item).ConvertToEntity<DeviceVariable>(true);
|
||||||
|
|
||||||
|
//var hasDup = rows.HasDuplicateElements<DeviceVariable>(nameof(DeviceVariable.Name), device.Name);
|
||||||
|
//var hasName = GetIdByName(device.Name) > 0;
|
||||||
|
//if (hasDup || hasName)
|
||||||
|
//{
|
||||||
|
// importPreviewOutput.HasError = true;
|
||||||
|
// importPreviewOutput.Results.Add((false, "名称重复"));
|
||||||
|
// return Task.CompletedTask;
|
||||||
|
//}
|
||||||
|
//转化设备名称
|
||||||
|
item.TryGetValue(ExportHelpers.DeviceName, out var value);
|
||||||
|
var deviceName = value?.ToString();
|
||||||
|
cacheDeviceDicts.TryGetValue(deviceName, out var device);
|
||||||
|
var deviceId = device?.Id;
|
||||||
|
if (deviceId == null)
|
||||||
|
{
|
||||||
|
//找不到对应的设备
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, $"{deviceName}设备不存在"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//变量ID和设备ID都需要手动补录
|
||||||
|
variable.DeviceId = deviceId.Value;
|
||||||
|
variable.Id = dbVariableDicts.TryGetValue(variable.Name, out var dbvar1) ? dbvar1.Id : YitIdHelper.NextId();
|
||||||
|
}
|
||||||
|
|
||||||
|
variables.Add(variable);
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, "成功"));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, ex.Message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
importPreviewOutput.Data = variables.OrderBy(a => a.Id).ToDictionary(a => a.Name);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int row = 1;
|
||||||
|
ImportPreviewOutput<string> importPreviewOutput = new();
|
||||||
|
ImportPreviews.Add(sheetName, importPreviewOutput);
|
||||||
|
|
||||||
|
//插件属性需加上前置名称
|
||||||
|
var newName = ExportHelpers.PluginLeftName + sheetName;
|
||||||
|
var pluginId = _driverPluginService.GetIdByName(newName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pluginId == null)
|
||||||
|
{
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, $"插件{newName}不存在"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var driverPlugin = _driverPluginService.GetDriverPluginById(pluginId.Value);
|
||||||
|
using var serviceScope = _scopeFactory.CreateScope();
|
||||||
|
var pluginSingletonService = serviceScope.ServiceProvider.GetService<PluginSingletonService>();
|
||||||
|
var driver = (UpLoadBase)pluginSingletonService.GetDriver(YitIdHelper.NextId(), driverPlugin);
|
||||||
|
var propertys = driver.VariablePropertys.GetType().GetAllProps()
|
||||||
|
.Where(a => a.GetCustomAttribute<VariablePropertyAttribute>() != null)
|
||||||
|
.ToDictionary(a => a.FindDisplayAttribute(a => a.GetCustomAttribute<VariablePropertyAttribute>()?.Description));
|
||||||
|
|
||||||
|
var cacheUpdeviceDicts = _uploadDeviceService.GetCacheList().ToDictionary(a => a.Name);
|
||||||
|
rows.ParallelForEach(item =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
List<DependencyProperty> dependencyProperties = new List<DependencyProperty>();
|
||||||
|
foreach (var keyValuePair in item)
|
||||||
|
{
|
||||||
|
if (propertys.TryGetValue(keyValuePair.Key, out var propertyInfo))
|
||||||
|
{
|
||||||
|
dependencyProperties.Add(new()
|
||||||
|
{
|
||||||
|
PropertyName = propertyInfo.Name,
|
||||||
|
Description = keyValuePair.Key.ToString(),
|
||||||
|
Value = keyValuePair.Value?.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//转化插件名称
|
||||||
|
item.TryGetValue(ExportHelpers.DeviceVariableSheetName, out var variableNameObj);
|
||||||
|
item.TryGetValue(ExportHelpers.UploadDeviceSheetName, out var uploadDevName);
|
||||||
|
var variableName = variableNameObj?.ToString();
|
||||||
|
|
||||||
|
if (uploadDevName != null)
|
||||||
|
{
|
||||||
|
cacheUpdeviceDicts.TryGetValue(uploadDevName.ToString(), out var uploadDevice);
|
||||||
|
|
||||||
|
var has = deviceImportPreview.Data.TryGetValue(variableName, out var deviceVariable);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
if (uploadDevice != null)
|
||||||
|
{
|
||||||
|
deviceVariable.VariablePropertys?.AddOrUpdate(uploadDevice.Id, a => dependencyProperties, (a, b) => dependencyProperties);
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, "成功"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, $"上传设备{uploadDevName}不存在"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, $"上传设备{uploadDevName}不存在"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), true, $"上传设备{uploadDevName}不存在"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, ex.Message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
importPreviewOutput.HasError = true;
|
||||||
|
importPreviewOutput.Results.Add((Interlocked.Add(ref row, 1), false, ex.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -667,28 +814,16 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
|||||||
if (item.Key == ExportHelpers.DeviceVariableSheetName)
|
if (item.Key == ExportHelpers.DeviceVariableSheetName)
|
||||||
{
|
{
|
||||||
var collectDeviceImports = ((ImportPreviewOutput<DeviceVariable>)item.Value).Data;
|
var collectDeviceImports = ((ImportPreviewOutput<DeviceVariable>)item.Value).Data;
|
||||||
collectDevices = collectDeviceImports.Adapt<List<DeviceVariable>>();
|
collectDevices = collectDeviceImports.Values.ToList();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Context.CurrentConnectionConfig.DbType == DbType.Sqlite
|
await Context.Utilities.PageEachAsync(collectDevices, 10000, async pageList =>
|
||||||
|| Context.CurrentConnectionConfig.DbType == DbType.SqlServer
|
|
||||||
|| Context.CurrentConnectionConfig.DbType == DbType.MySql
|
|
||||||
|| Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//大量数据插入/更新
|
await Context.Storageable(pageList).ExecuteCommandAsync();
|
||||||
var x = await Context.Storageable(collectDevices).ToStorageAsync();
|
});
|
||||||
await x.BulkCopyAsync();//不存在插入
|
|
||||||
await x.BulkUpdateAsync();//存在更新
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//其他数据库使用普通插入/更新
|
|
||||||
await Context.Storageable(collectDevices).ExecuteCommandAsync();
|
|
||||||
}
|
|
||||||
DeleteVariableFromCache();
|
DeleteVariableFromCache();
|
||||||
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -532,10 +532,10 @@ public class AlarmWorker : BackgroundService
|
|||||||
_logger.LogWarning(ex, "写入历史报警失败");
|
_logger.LogWarning(ex, "写入历史报警失败");
|
||||||
|
|
||||||
var cacheDatas = hisalarm.ChunkTrivialBetter(500);
|
var cacheDatas = hisalarm.ChunkTrivialBetter(500);
|
||||||
await cacheDatas.ForeachAsync(async a =>
|
foreach (var a in cacheDatas)
|
||||||
{
|
{
|
||||||
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,6 +356,8 @@ public class CollectDeviceCore : DisposableObject
|
|||||||
{
|
{
|
||||||
foreach (var deviceVariableSourceRead in DeviceVariableSourceReads)
|
foreach (var deviceVariableSourceRead in DeviceVariableSourceReads)
|
||||||
{
|
{
|
||||||
|
await Task.Delay(10);
|
||||||
|
|
||||||
if (Device?.KeepRun == false)
|
if (Device?.KeepRun == false)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -381,11 +383,11 @@ public class CollectDeviceCore : DisposableObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var deviceVariableMedRead in DeviceVariableMedReads)
|
foreach (var deviceVariableMedRead in DeviceVariableMedReads)
|
||||||
{
|
{
|
||||||
|
await Task.Delay(10);
|
||||||
if (Device?.KeepRun == false)
|
if (Device?.KeepRun == false)
|
||||||
continue;
|
continue;
|
||||||
if (StoppingToken.IsCancellationRequested)
|
if (StoppingToken.IsCancellationRequested)
|
||||||
@@ -738,8 +740,7 @@ public class CollectDeviceCore : DisposableObject
|
|||||||
{
|
{
|
||||||
_pluginService.DeleteDriver(DeviceId, Device.PluginId);
|
_pluginService.DeleteDriver(DeviceId, Device.PluginId);
|
||||||
}
|
}
|
||||||
GC.Collect();
|
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ public class CollectDeviceThread : IDisposable
|
|||||||
{
|
{
|
||||||
await device.BeforeActionAsync(StoppingToken.Token);
|
await device.BeforeActionAsync(StoppingToken.Token);
|
||||||
}
|
}
|
||||||
|
await Task.Delay(100, StoppingToken.Token);
|
||||||
}
|
}
|
||||||
while (!CollectDeviceCores.All(a => a.IsExited))
|
while (!CollectDeviceCores.All(a => a.IsExited))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ public class CollectDeviceWorker : BackgroundService
|
|||||||
StartAllDeviceThreads();
|
StartAllDeviceThreads();
|
||||||
_logger.LogInformation("启动其他服务线程");
|
_logger.LogInformation("启动其他服务线程");
|
||||||
StartOtherHostService();
|
StartOtherHostService();
|
||||||
|
GC.Collect();
|
||||||
|
GC.WaitForPendingFinalizers();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -229,6 +231,7 @@ public class CollectDeviceWorker : BackgroundService
|
|||||||
deviceCollectCore.Init(collectDeviceRunTime);
|
deviceCollectCore.Init(collectDeviceRunTime);
|
||||||
|
|
||||||
DeviceThread(deviceCollectCore);
|
DeviceThread(deviceCollectCore);
|
||||||
|
await Task.Delay(10);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -483,51 +486,61 @@ public class CollectDeviceWorker : BackgroundService
|
|||||||
await RestartDeviceThreadAsync();
|
await RestartDeviceThreadAsync();
|
||||||
while (!stoppingToken.IsCancellationRequested)
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
//这里不采用CancellationToken控制子线程,直接循环保持,结束时调用子设备线程Dispose
|
try
|
||||||
//检测设备采集线程假死
|
|
||||||
var num = CollectDeviceCores.Count;
|
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
{
|
||||||
CollectDeviceCore devcore = CollectDeviceCores[i];
|
|
||||||
if (devcore.Device != null)
|
|
||||||
|
//这里不采用CancellationToken控制子线程,直接循环保持,结束时调用子设备线程Dispose
|
||||||
|
//检测设备采集线程假死
|
||||||
|
var num = CollectDeviceCores.Count;
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
|
CollectDeviceCore devcore = CollectDeviceCores[i];
|
||||||
if (
|
if (devcore.Device != null)
|
||||||
(devcore.Device.ActiveTime != DateTime.MinValue
|
|
||||||
&& devcore.Device.ActiveTime.AddMinutes(3) <= DateTime.UtcNow)
|
|
||||||
|| devcore.IsInitSuccess == false
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (devcore.StoppingTokens.LastOrDefault()?.Token.IsCancellationRequested == true)
|
|
||||||
continue;
|
|
||||||
if (devcore.Device.DeviceStatus == DeviceStatusEnum.Pause)
|
|
||||||
continue;
|
|
||||||
if (!devcore.IsInitSuccess)
|
|
||||||
_logger?.LogWarning(devcore.Device.Name + "初始化失败,重启线程中");
|
|
||||||
else
|
|
||||||
_logger?.LogWarning(devcore.Device.Name + "采集线程假死,重启线程中");
|
|
||||||
await UpDeviceThreadAsync(devcore.DeviceId, false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger?.LogTrace(devcore.Device.Name + "线程检测正常");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (
|
||||||
if (devcore.Device.DeviceStatus == DeviceStatusEnum.OffLine)
|
(devcore.Device.ActiveTime != DateTime.MinValue
|
||||||
{
|
&& devcore.Device.ActiveTime.AddMinutes(3) <= DateTime.UtcNow)
|
||||||
if (devcore.Device.IsRedundant && _collectDeviceService.GetCacheList().Any(a => a.Id == devcore.Device.RedundantDeviceId))
|
|| devcore.IsInitSuccess == false
|
||||||
|
)
|
||||||
{
|
{
|
||||||
await UpDeviceRedundantThreadAsync(devcore.Device.Id);
|
if (devcore.StoppingTokens.LastOrDefault()?.Token.IsCancellationRequested == true)
|
||||||
|
continue;
|
||||||
|
if (devcore.Device.DeviceStatus == DeviceStatusEnum.Pause)
|
||||||
|
continue;
|
||||||
|
if (!devcore.IsInitSuccess)
|
||||||
|
_logger?.LogWarning(devcore.Device.Name + "初始化失败,重启线程中");
|
||||||
|
else
|
||||||
|
_logger?.LogWarning(devcore.Device.Name + "采集线程假死,重启线程中");
|
||||||
|
await UpDeviceThreadAsync(devcore.DeviceId, false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger?.LogTrace(devcore.Device.Name + "线程检测正常");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (devcore.Device.DeviceStatus == DeviceStatusEnum.OffLine)
|
||||||
|
{
|
||||||
|
if (devcore.Device.IsRedundant && _collectDeviceService.GetCacheList().Any(a => a.Id == devcore.Device.RedundantDeviceId))
|
||||||
|
{
|
||||||
|
await UpDeviceRedundantThreadAsync(devcore.Device.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Task.Delay(300000, stoppingToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(300000, stoppingToken);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using ThingsGateway.Core.Extension;
|
|
||||||
using ThingsGateway.Foundation;
|
using ThingsGateway.Foundation;
|
||||||
using ThingsGateway.Foundation.Extension;
|
using ThingsGateway.Foundation.Extension;
|
||||||
using ThingsGateway.Foundation.Extension.Enumerator;
|
using ThingsGateway.Foundation.Extension.Enumerator;
|
||||||
@@ -245,11 +244,10 @@ public class HistoryValueWorker : BackgroundService
|
|||||||
if (LastIsSuccess)
|
if (LastIsSuccess)
|
||||||
_logger.LogWarning(ex, "写入历史数据失败");
|
_logger.LogWarning(ex, "写入历史数据失败");
|
||||||
var cacheDatas = collecthis.ChunkTrivialBetter(500);
|
var cacheDatas = collecthis.ChunkTrivialBetter(500);
|
||||||
await cacheDatas.ForeachAsync(async a =>
|
foreach (var a in cacheDatas)
|
||||||
{
|
{
|
||||||
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
||||||
});
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,10 +271,10 @@ public class HistoryValueWorker : BackgroundService
|
|||||||
if (LastIsSuccess)
|
if (LastIsSuccess)
|
||||||
_logger.LogWarning(ex, "写入历史数据失败");
|
_logger.LogWarning(ex, "写入历史数据失败");
|
||||||
var cacheDatas = changehis.ChunkTrivialBetter(500);
|
var cacheDatas = changehis.ChunkTrivialBetter(500);
|
||||||
await cacheDatas.ForeachAsync(async a =>
|
foreach (var a in cacheDatas)
|
||||||
{
|
{
|
||||||
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public class UploadDeviceThread : IDisposable
|
|||||||
{
|
{
|
||||||
device.Logger?.LogError(ex, "报文日志添加失败");
|
device.Logger?.LogError(ex, "报文日志添加失败");
|
||||||
}
|
}
|
||||||
|
await Task.Delay(100, StoppingToken.Token);
|
||||||
await device.BeforeActionAsync(StoppingToken.Token);
|
await device.BeforeActionAsync(StoppingToken.Token);
|
||||||
}
|
}
|
||||||
while (!UploadDeviceCores.All(a => a.IsExited))
|
while (!UploadDeviceCores.All(a => a.IsExited))
|
||||||
|
|||||||
@@ -354,39 +354,48 @@ public class UploadDeviceWorker : BackgroundService
|
|||||||
|
|
||||||
while (!stoppingToken.IsCancellationRequested)
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
//这里不采用CancellationToken控制子线程,直接循环保持,结束时调用子设备线程Dispose
|
try
|
||||||
//检测设备上传线程假死
|
|
||||||
var num = UploadDeviceCores.Count;
|
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
{
|
||||||
UploadDeviceCore devcore = UploadDeviceCores[i];
|
|
||||||
if (devcore.Device != null)
|
|
||||||
|
//这里不采用CancellationToken控制子线程,直接循环保持,结束时调用子设备线程Dispose
|
||||||
|
//检测设备上传线程假死
|
||||||
|
var num = UploadDeviceCores.Count;
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
if (
|
UploadDeviceCore devcore = UploadDeviceCores[i];
|
||||||
(devcore.Device.ActiveTime != DateTime.MinValue
|
if (devcore.Device != null)
|
||||||
&& devcore.Device.ActiveTime.AddMinutes(3) <= DateTime.UtcNow)
|
|
||||||
|| devcore.IsInitSuccess == false
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (devcore.StoppingTokens.LastOrDefault()?.Token.IsCancellationRequested == true)
|
if (
|
||||||
continue;
|
(devcore.Device.ActiveTime != DateTime.MinValue
|
||||||
if (devcore.Device.DeviceStatus == DeviceStatusEnum.Pause)
|
&& devcore.Device.ActiveTime.AddMinutes(3) <= DateTime.UtcNow)
|
||||||
continue;
|
|| devcore.IsInitSuccess == false
|
||||||
if (!devcore.IsInitSuccess)
|
)
|
||||||
_logger?.LogWarning(devcore.Device.Name + "初始化失败,重启线程中");
|
{
|
||||||
|
if (devcore.StoppingTokens.LastOrDefault()?.Token.IsCancellationRequested == true)
|
||||||
|
continue;
|
||||||
|
if (devcore.Device.DeviceStatus == DeviceStatusEnum.Pause)
|
||||||
|
continue;
|
||||||
|
if (!devcore.IsInitSuccess)
|
||||||
|
_logger?.LogWarning(devcore.Device.Name + "初始化失败,重启线程中");
|
||||||
|
else
|
||||||
|
_logger?.LogWarning(devcore.Device.Name + "上传线程假死,重启线程中");
|
||||||
|
await UpDeviceThreadAsync(devcore.DeviceId);
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
_logger?.LogWarning(devcore.Device.Name + "上传线程假死,重启线程中");
|
{
|
||||||
await UpDeviceThreadAsync(devcore.DeviceId);
|
_logger?.LogTrace(devcore.Device.Name + "线程检测正常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger?.LogTrace(devcore.Device.Name + "线程检测正常");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
await Task.Delay(300000, stoppingToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, ToString());
|
||||||
}
|
}
|
||||||
await Task.Delay(300000, stoppingToken);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,12 +185,16 @@ namespace ThingsGateway.Web.Page
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_collectDeviceCores?.FirstOrDefault()?.Device == null)
|
{
|
||||||
|
_collectDeviceGroups = _globalDeviceData.CollectDevices.Adapt<List<CollectDevice>>()?.Select(a => a.DeviceGroup)?.Where(a => a != null).Distinct()?.ToList() ?? new();
|
||||||
|
_collectDeviceCores = CollectDeviceHostService?.CollectDeviceCores?.WhereIf(!_collectDeviceGroup.IsNullOrEmpty(), a => a.Device?.DeviceGroup == _collectDeviceGroup).ToList() ?? new();
|
||||||
|
}
|
||||||
|
if (_collectDeviceCores?.FirstOrDefault()?.Device == null || CollectDeviceHostService?.CollectDeviceCores.Count != _collectDeviceCores.Count)
|
||||||
{
|
{
|
||||||
collectDeviceQuery();
|
collectDeviceQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_uploadDeviceCores?.FirstOrDefault()?.Device == null)
|
if (_uploadDeviceCores?.FirstOrDefault()?.Device == null || UploadDeviceHostService?.UploadDeviceCores.Count != _uploadDeviceCores.Count)
|
||||||
{
|
{
|
||||||
uploadDeviceQuery();
|
uploadDeviceQuery();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -488,7 +488,7 @@
|
|||||||
var data=GetDriverProperties(UploadDevices.FirstOrDefault(a=>a.Id==choiceUploadDeviceId).PluginId,context.VariablePropertys.ContainsKey(choiceUploadDeviceId)?context.VariablePropertys[choiceUploadDeviceId]:null);
|
var data=GetDriverProperties(UploadDevices.FirstOrDefault(a=>a.Id==choiceUploadDeviceId).PluginId,context.VariablePropertys.ContainsKey(choiceUploadDeviceId)?context.VariablePropertys[choiceUploadDeviceId]:null);
|
||||||
if(data?.Count>0)
|
if(data?.Count>0)
|
||||||
{
|
{
|
||||||
context.VariablePropertys.AddOrUpdate(choiceUploadDeviceId, data);
|
context.VariablePropertys.AddOrUpdate(choiceUploadDeviceId,a=> data,(a,b)=>data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace ThingsGateway.Web.Page
|
|||||||
{
|
{
|
||||||
isImport = true;
|
isImport = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
ImportPreviews.Clear();
|
||||||
ImportPreviews = await Preview.Invoke(file);
|
ImportPreviews = await Preview.Invoke(file);
|
||||||
Step = 2;
|
Step = 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -396,7 +396,7 @@
|
|||||||
var data=GetDriverProperties(UploadDevices.FirstOrDefault(a=>a.Id==choiceUploadDeviceId).PluginId,context.VariablePropertys.ContainsKey(choiceUploadDeviceId)?context.VariablePropertys[choiceUploadDeviceId]:null);
|
var data=GetDriverProperties(UploadDevices.FirstOrDefault(a=>a.Id==choiceUploadDeviceId).PluginId,context.VariablePropertys.ContainsKey(choiceUploadDeviceId)?context.VariablePropertys[choiceUploadDeviceId]:null);
|
||||||
if(data?.Count>0)
|
if(data?.Count>0)
|
||||||
{
|
{
|
||||||
context.VariablePropertys.AddOrUpdate(choiceUploadDeviceId, data);
|
context.VariablePropertys.AddOrUpdate(choiceUploadDeviceId,a=> data,(a,b)=>data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ public class Program
|
|||||||
{
|
{
|
||||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
System.IO.Directory.SetCurrentDirectory(AppContext.BaseDirectory);
|
System.IO.Directory.SetCurrentDirectory(AppContext.BaseDirectory);
|
||||||
|
ThreadPool.SetMinThreads(2000, 2000);
|
||||||
|
ThreadPool.SetMaxThreads(1000000, 1000000);
|
||||||
|
|
||||||
#if KINGVIEW //读取组态王不能后台启动,所以这里多出来一个解决方案配置
|
#if KINGVIEW //读取组态王不能后台启动,所以这里多出来一个解决方案配置
|
||||||
SevicesExtension.KINGVIEWCONFIG();
|
SevicesExtension.KINGVIEWCONFIG();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||||
<Configurations>Debug;Release;KINGVIEW</Configurations>
|
<Configurations>Debug;Release;KINGVIEW</Configurations>
|
||||||
<Platforms>AnyCPU;x86</Platforms>
|
<Platforms>AnyCPU;x86</Platforms>
|
||||||
<ServerGarbageCollection>false</ServerGarbageCollection>
|
<!--<ServerGarbageCollection>false</ServerGarbageCollection>-->
|
||||||
<!--切换为工作站GC策略-->
|
<!--切换为工作站GC策略-->
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user