523 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			523 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| #region copyright
 | ||
| //------------------------------------------------------------------------------
 | ||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
 | ||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有
 | ||
| //  源代码使用协议遵循本仓库的开源协议及附加协议
 | ||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
 | ||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
 | ||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/
 | ||
| //  QQ群:605534569
 | ||
| //------------------------------------------------------------------------------
 | ||
| #endregion
 | ||
| 
 | ||
| using Furion;
 | ||
| using Furion.DependencyInjection;
 | ||
| using Furion.FriendlyException;
 | ||
| 
 | ||
| using Mapster;
 | ||
| 
 | ||
| using Microsoft.AspNetCore.Components.Forms;
 | ||
| 
 | ||
| using MiniExcelLibs;
 | ||
| 
 | ||
| using System.Collections.Concurrent;
 | ||
| using System.Dynamic;
 | ||
| using System.Reflection;
 | ||
| 
 | ||
| using ThingsGateway.Admin.Application;
 | ||
| using ThingsGateway.Application.Extensions;
 | ||
| using ThingsGateway.Foundation.Extension.Generic;
 | ||
| 
 | ||
| using Yitter.IdGenerator;
 | ||
| 
 | ||
| namespace ThingsGateway.Application;
 | ||
| 
 | ||
| /// <inheritdoc cref="ICollectDeviceService"/>
 | ||
| [Injection(Proxy = typeof(OperDispatchProxy))]
 | ||
| public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceService
 | ||
| {
 | ||
|     private readonly IDriverPluginService _driverPluginService;
 | ||
|     private readonly IFileService _fileService;
 | ||
| 
 | ||
|     /// <inheritdoc cref="ICollectDeviceService"/>
 | ||
|     public CollectDeviceService(
 | ||
|     IDriverPluginService driverPluginService,
 | ||
|     IFileService fileService
 | ||
|         )
 | ||
|     {
 | ||
|         _fileService = fileService;
 | ||
| 
 | ||
|         _driverPluginService = driverPluginService;
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     [OperDesc("添加采集设备")]
 | ||
|     public async Task AddAsync(CollectDevice input)
 | ||
|     {
 | ||
|         var account_Id = GetIdByName(input.Name);
 | ||
|         if (account_Id > 0)
 | ||
|             throw Oops.Bah($"存在重复的名称:{input.Name}");
 | ||
|         await InsertAsync(input);//添加数据
 | ||
|         CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_CollectDevice);//cache删除
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     [OperDesc("复制采集设备")]
 | ||
|     public async Task CopyDevAsync(IEnumerable<CollectDevice> input)
 | ||
|     {
 | ||
|         var newDevs = input.Adapt<List<CollectDevice>>();
 | ||
|         newDevs.ForEach(a =>
 | ||
|         {
 | ||
|             a.Id = YitIdHelper.NextId();
 | ||
|             a.Name = $"Copy-{a.Name}-{a.Id}";
 | ||
|         });
 | ||
| 
 | ||
|         var result = await InsertRangeAsync(newDevs);//添加数据
 | ||
|         CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_CollectDevice);//cache删除
 | ||
| 
 | ||
|     }
 | ||
|     /// <inheritdoc/>
 | ||
|     [OperDesc("复制采集设备与变量")]
 | ||
|     public async Task CopyDevAndVarAsync(IEnumerable<CollectDevice> input)
 | ||
|     {
 | ||
|         var variableService = App.GetService<IVariableService>();
 | ||
|         List<DeviceVariable> variables = new();
 | ||
|         var newDevs = input.Adapt<List<CollectDevice>>();
 | ||
|         foreach (var item in newDevs)
 | ||
|         {
 | ||
|             var newId = YitIdHelper.NextId();
 | ||
|             var deviceVariables = await Context.Queryable<DeviceVariable>().Where(a => a.DeviceId == item.Id).ToListAsync();
 | ||
|             deviceVariables.ForEach(b =>
 | ||
|             {
 | ||
|                 b.Id = YitIdHelper.NextId();
 | ||
|                 b.DeviceId = newId;
 | ||
|                 b.Name = $"Copy-{b.Name}-{b.Id}";
 | ||
|             });
 | ||
|             variables.AddRange(deviceVariables);
 | ||
|             item.Id = newId;
 | ||
|             item.Name = $"Copy-{item.Name}-{newId}";
 | ||
|         }
 | ||
| 
 | ||
|         var result = await itenant.UseTranAsync(async () =>
 | ||
|         {
 | ||
|             await InsertRangeAsync(newDevs);//添加数据
 | ||
|             await Context.Insertable(variables).ExecuteCommandAsync();//添加数据
 | ||
|         });
 | ||
| 
 | ||
|         if (result.IsSuccess)
 | ||
|         {
 | ||
|             CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_CollectDevice);//cache删除
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|             throw Oops.Oh(result.ErrorMessage);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     public long? GetIdByName(string name)
 | ||
|     {
 | ||
|         var data = GetCacheList(false);
 | ||
|         return data.FirstOrDefault(it => it.Name == name)?.Id;
 | ||
|     }
 | ||
|     /// <inheritdoc/>
 | ||
|     public string GetNameById(long id)
 | ||
|     {
 | ||
|         var data = GetCacheList(false);
 | ||
|         return data.FirstOrDefault(it => it.Id == id)?.Name;
 | ||
|     }
 | ||
|     /// <inheritdoc/>
 | ||
|     public List<DeviceTree> GetTree()
 | ||
|     {
 | ||
|         var data = GetCacheList(false);
 | ||
|         var trees = data.GetTree();
 | ||
|         return trees;
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     [OperDesc("删除采集设备")]
 | ||
|     public async Task DeleteAsync(params long[] input)
 | ||
|     {
 | ||
|         //获取所有ID
 | ||
|         if (input.Length > 0)
 | ||
|         {
 | ||
|             var result = await DeleteByIdsAsync(input.Cast<object>().ToArray());
 | ||
|             var variableService = App.GetService<IVariableService>();
 | ||
|             await Context.Deleteable<DeviceVariable>(it => input.Contains(it.DeviceId)).ExecuteCommandAsync();
 | ||
|             variableService.DeleteVariableFromCache();
 | ||
|             if (result)
 | ||
|             {
 | ||
|                 CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_CollectDevice);//cache删除
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     [OperDesc("编辑采集设备")]
 | ||
|     public async Task EditAsync(CollectDeviceEditInput input)
 | ||
|     {
 | ||
|         var account_Id = GetIdByName(input.Name);
 | ||
|         if (account_Id > 0 && account_Id != input.Id)
 | ||
|             throw Oops.Bah($"存在重复的名称:{input.Name}");
 | ||
| 
 | ||
|         if (await Context.Updateable(input.Adapt<CollectDevice>()).ExecuteCommandAsync() > 0)//修改数据
 | ||
|             CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_CollectDevice);//cache删除
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     public async Task<SqlSugarPagedList<CollectDevice>> PageAsync(CollectDevicePageInput input)
 | ||
|     {
 | ||
|         var query = GetPage(input);
 | ||
|         var pageInfo = await query.ToPagedListAsync(input.Current, input.Size);//分页
 | ||
|         return pageInfo;
 | ||
|     }
 | ||
|     /// <inheritdoc/>
 | ||
|     private ISugarQueryable<CollectDevice> GetPage(CollectDevicePageInput input)
 | ||
|     {
 | ||
|         long? pluginid = 0;
 | ||
|         if (!string.IsNullOrEmpty(input.PluginName))
 | ||
|         {
 | ||
|             pluginid = _driverPluginService.GetCacheList(false).FirstOrDefault(it => it.AssembleName.Contains(input.PluginName))?.Id;
 | ||
|         }
 | ||
|         ISugarQueryable<CollectDevice> query = Context.Queryable<CollectDevice>()
 | ||
|          .WhereIF(!string.IsNullOrEmpty(input.Name), u => u.Name.Contains(input.Name))
 | ||
|          .WhereIF(!string.IsNullOrEmpty(input.DeviceGroup), u => u.DeviceGroup == input.DeviceGroup)
 | ||
|          .WhereIF(!string.IsNullOrEmpty(input.PluginName), u => u.PluginId == (pluginid ?? 0));
 | ||
|         for (int i = 0; i < input.SortField.Count; i++)
 | ||
|         {
 | ||
|             query = query.OrderByIF(!string.IsNullOrEmpty(input.SortField[i]), $"{input.SortField[i]} {(input.SortDesc[i] ? "desc" : "asc")}");
 | ||
|         }
 | ||
|         query = query.OrderBy(it => it.Id, OrderByType.Desc);//排序
 | ||
| 
 | ||
|         return query;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     public CollectDevice GetDeviceById(long Id)
 | ||
|     {
 | ||
|         var data = GetCacheList();
 | ||
|         return data.FirstOrDefault(it => it.Id == Id);
 | ||
|     }
 | ||
|     /// <inheritdoc/>
 | ||
|     public List<CollectDevice> GetCacheList(bool isMapster = true)
 | ||
|     {
 | ||
|         //先从Cache拿
 | ||
|         var collectDevice = CacheStatic.Cache.Get<List<CollectDevice>>(ThingsGatewayCacheConst.Cache_CollectDevice, isMapster);
 | ||
|         if (collectDevice == null)
 | ||
|         {
 | ||
|             collectDevice = Context.Queryable<CollectDevice>().ToList();
 | ||
|             if (collectDevice != null)
 | ||
|             {
 | ||
|                 //插入Cache
 | ||
|                 CacheStatic.Cache.Set(ThingsGatewayCacheConst.Cache_CollectDevice, collectDevice, isMapster);
 | ||
|             }
 | ||
|         }
 | ||
|         return collectDevice;
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     public async Task<List<CollectDeviceRunTime>> GetCollectDeviceRuntimeAsync(long devId = 0)
 | ||
|     {
 | ||
|         if (devId == 0)
 | ||
|         {
 | ||
|             var devices = GetCacheList(false).Where(a => a.Enable).ToList();
 | ||
|             var runtime = devices.Adapt<List<CollectDeviceRunTime>>().ToDictionary(a => a.Id);
 | ||
|             var variableService = App.GetService<IVariableService>();
 | ||
|             var collectVariableRunTimes = await variableService.GetDeviceVariableRuntimeAsync();
 | ||
|             ConcurrentDictionary<long, DriverPlugin> driverPlugins = new(_driverPluginService.GetCacheList(false).ToDictionary(a => a.Id));
 | ||
|             runtime.Values.ParallelForEach(device =>
 | ||
|            {
 | ||
|                driverPlugins.TryGetValue(device.PluginId, out var driverPlugin);
 | ||
|                device.PluginName = driverPlugin?.AssembleName;
 | ||
|                device.DeviceVariableRunTimes = collectVariableRunTimes.Where(a => a.DeviceId == device.Id).ToList();
 | ||
|            });
 | ||
| 
 | ||
|             collectVariableRunTimes.ParallelForEach(variable =>
 | ||
|             {
 | ||
|                 if (runtime.TryGetValue(variable.DeviceId, out var device))
 | ||
|                 {
 | ||
|                     variable.CollectDeviceRunTime = device;
 | ||
|                     variable.DeviceName = device.Name;
 | ||
|                 }
 | ||
|             });
 | ||
|             return runtime.Values.ToList();
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|             var device = GetCacheList(false).Where(a => a.Enable).ToList().FirstOrDefault(it => it.Id == devId);
 | ||
|             var runtime = device.Adapt<CollectDeviceRunTime>();
 | ||
|             var variableService = App.GetService<IVariableService>();
 | ||
|             if (runtime == null) return new() { runtime };
 | ||
|             var pluginName = _driverPluginService.GetNameById(device.PluginId);
 | ||
|             var collectVariableRunTimes = await variableService.GetDeviceVariableRuntimeAsync(devId);
 | ||
|             runtime.PluginName = pluginName;
 | ||
|             runtime.DeviceVariableRunTimes = collectVariableRunTimes;
 | ||
| 
 | ||
|             collectVariableRunTimes.ParallelForEach(variable =>
 | ||
|            {
 | ||
|                variable.CollectDeviceRunTime = runtime;
 | ||
|                variable.DeviceName = runtime.Name;
 | ||
|            });
 | ||
|             return new() { runtime };
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     #region 导入导出
 | ||
|     /// <inheritdoc/>
 | ||
|     public async Task<MemoryStream> ExportFileAsync(CollectDeviceInput input)
 | ||
|     {
 | ||
|         var query = GetPage(input.Adapt<CollectDevicePageInput>());
 | ||
|         var data = await query.ToListAsync();
 | ||
|         return await ExportFileAsync(data);
 | ||
|     }
 | ||
|     /// <inheritdoc/>
 | ||
|     [OperDesc("导出采集设备表", IsRecordPar = false)]
 | ||
|     public async Task<MemoryStream> ExportFileAsync(List<CollectDevice> devDatas = null)
 | ||
|     {
 | ||
|         devDatas ??= GetCacheList(false);
 | ||
| 
 | ||
|         //总数据
 | ||
|         Dictionary<string, object> sheets = new();
 | ||
|         //设备页
 | ||
|         List<Dictionary<string, object>> devExports = new();
 | ||
|         //设备附加属性,转成Dict<表名,List<Dict<列名,列数据>>>的形式
 | ||
|         Dictionary<string, List<Dictionary<string, object>>> devicePropertys = new();
 | ||
|         var driverPluginDicts = _driverPluginService.GetCacheList(false).ToDictionary(a => a.Id);
 | ||
|         var deviceDicts = devDatas.ToDictionary(a => a.Id);
 | ||
|         foreach (var devData in devDatas)
 | ||
|         {
 | ||
|             #region 设备sheet
 | ||
|             //设备页
 | ||
|             var data = devData.GetType().GetPropertiesWithCache().Where(a => a.GetCustomAttribute<IgnoreExcelAttribute>() == null);
 | ||
|             Dictionary<string, object> devExport = new();
 | ||
|             foreach (var item in data)
 | ||
|             {
 | ||
|                 //描述
 | ||
|                 var desc = item.FindDisplayAttribute();
 | ||
|                 //数据源增加
 | ||
|                 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, driverPlugin.AssembleName);
 | ||
|             //设备实体没有包含冗余设备名称,手动插入
 | ||
|             devExport.Add(ExportHelpers.RedundantDeviceName, redundantDevice?.Name);
 | ||
| 
 | ||
|             //添加完整设备信息
 | ||
|             devExports.Add(devExport);
 | ||
| 
 | ||
|             #endregion
 | ||
| 
 | ||
|             #region 插件sheet
 | ||
|             //插件属性
 | ||
|             //单个设备的行数据
 | ||
|             Dictionary<string, object> driverInfo = new();
 | ||
|             //没有包含设备名称,手动插入
 | ||
|             if (devData.DevicePropertys.Count > 0)
 | ||
|             {
 | ||
|                 driverInfo.Add(ExportHelpers.DeviceName, devData.Name);
 | ||
|             }
 | ||
|             foreach (var item in devData.DevicePropertys ?? new())
 | ||
|             {
 | ||
|                 //添加对应属性数据
 | ||
|                 driverInfo.Add(item.Description, item.Value);
 | ||
|             }
 | ||
| 
 | ||
|             //插件名称去除首部ThingsGateway.作为表名
 | ||
|             var pluginName = driverPlugin.AssembleName.Replace(ExportHelpers.PluginLeftName, "");
 | ||
|             if (devicePropertys.ContainsKey(pluginName))
 | ||
|             {
 | ||
|                 if (driverInfo.Count > 0)
 | ||
|                     devicePropertys[pluginName].Add(driverInfo);
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 if (driverInfo.Count > 0)
 | ||
|                     devicePropertys.Add(pluginName, new() { driverInfo });
 | ||
|             }
 | ||
| 
 | ||
|             #endregion
 | ||
|         }
 | ||
| 
 | ||
|         //添加设备页
 | ||
|         sheets.Add(ExportHelpers.CollectDeviceSheetName, devExports);
 | ||
|         //添加插件属性页
 | ||
|         foreach (var item in devicePropertys)
 | ||
|         {
 | ||
|             sheets.Add(item.Key, item.Value);
 | ||
|         }
 | ||
| 
 | ||
|         var memoryStream = new MemoryStream();
 | ||
|         await memoryStream.SaveAsAsync(sheets);
 | ||
|         return memoryStream;
 | ||
|     }
 | ||
| 
 | ||
|     /// <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 deviceDicts = GetCacheList(false).ToDictionary(a => a.Name);
 | ||
|         var pluginDicts = _driverPluginService.GetCacheList(false).ToDictionary(a => a.AssembleName);
 | ||
| 
 | ||
|         //导入检验结果
 | ||
|         Dictionary<string, ImportPreviewOutputBase> ImportPreviews = new();
 | ||
|         //设备页
 | ||
|         ImportPreviewOutput<CollectDevice> deviceImportPreview = new();
 | ||
|         foreach (var sheetName in sheetNames)
 | ||
|         {
 | ||
|             //单页数据
 | ||
|             var rows = fs.Query(useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
 | ||
|             #region 采集设备sheet
 | ||
|             if (sheetName == ExportHelpers.CollectDeviceSheetName)
 | ||
|             {
 | ||
|                 int row = 1;
 | ||
|                 ImportPreviewOutput<CollectDevice> importPreviewOutput = new();
 | ||
|                 ImportPreviews.Add(sheetName, importPreviewOutput);
 | ||
|                 deviceImportPreview = importPreviewOutput;
 | ||
|                 List<CollectDevice> devices = new();
 | ||
|                 rows.ForEach(item =>
 | ||
|                {
 | ||
|                    try
 | ||
|                    {
 | ||
| 
 | ||
|                        var device = ((ExpandoObject)item).ConvertToEntity<CollectDevice>(true);
 | ||
|                        #region 特殊转化名称
 | ||
|                        //转化插件名称
 | ||
|                        var hasPlugin = item.TryGetValue(ExportHelpers.PluginName, out var pluginObj);
 | ||
| 
 | ||
|                        if (pluginObj == null || !pluginDicts.TryGetValue(pluginObj.ToString(), out var plugin))
 | ||
|                        {
 | ||
|                            //找不到对应的插件
 | ||
|                            importPreviewOutput.HasError = true;
 | ||
|                            importPreviewOutput.Results.Add((row++, false, $"{ExportHelpers.PluginName}不存在"));
 | ||
|                            return;
 | ||
|                        }
 | ||
|                        //转化冗余设备名称
 | ||
|                        var hasRedundant = item.TryGetValue(ExportHelpers.PluginName, out var redundantObj);
 | ||
| 
 | ||
|                        #endregion
 | ||
|                        //插件ID、设备ID、冗余设备ID都需要手动补录
 | ||
|                        device.PluginId = plugin.Id;
 | ||
|                        if (hasRedundant && deviceDicts.TryGetValue(redundantObj.ToString(), out var rendundantDevice))
 | ||
|                        {
 | ||
|                            device.RedundantDeviceId = rendundantDevice.Id;
 | ||
|                        }
 | ||
|                        device.Id = deviceDicts.TryGetValue(device.Name, out var collectDevice) ? collectDevice.Id : YitIdHelper.NextId();
 | ||
| 
 | ||
|                        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
 | ||
|             else
 | ||
|             {
 | ||
|                 int row = 1;
 | ||
|                 ImportPreviewOutput<string> importPreviewOutput = new();
 | ||
|                 ImportPreviews.Add(sheetName, importPreviewOutput);
 | ||
|                 //插件属性需加上前置名称
 | ||
|                 //var newName = ExportHelpers.PluginLeftName + sheetName;
 | ||
|                 var newName = sheetName;
 | ||
|                 var pluginId = _driverPluginService.GetIdByName(newName);
 | ||
|                 if (pluginId == null)
 | ||
|                 {
 | ||
|                     importPreviewOutput.HasError = true;
 | ||
|                     importPreviewOutput.Results.Add((row++, false, $"插件{newName}不存在"));
 | ||
|                     continue;
 | ||
|                 }
 | ||
| 
 | ||
|                 var driverPlugin = _driverPluginService.GetDriverPluginById(pluginId.Value);
 | ||
|                 var pluginSingletonService = App.GetService<PluginSingletonService>();
 | ||
|                 var driver = (DriverBase)pluginSingletonService.GetDriver(driverPlugin);
 | ||
|                 var propertys = driver.DriverPropertys.GetType().GetPropertiesWithCache()
 | ||
|     .Where(a => a.GetCustomAttribute<DevicePropertyAttribute>() != null)
 | ||
|     .ToDictionary(a => a.FindDisplayAttribute(a => a.GetCustomAttribute<DevicePropertyAttribute>()?.Description));
 | ||
|                 rows.ForEach(item =>
 | ||
|                {
 | ||
|                    try
 | ||
|                    {
 | ||
| 
 | ||
|                        List<DependencyProperty> devices = new();
 | ||
|                        foreach (var keyValuePair in item)
 | ||
|                        {
 | ||
|                            if (propertys.TryGetValue(keyValuePair.Key, out var propertyInfo))
 | ||
|                            {
 | ||
|                                devices.Add(new()
 | ||
|                                {
 | ||
|                                    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)
 | ||
|                    {
 | ||
|                        importPreviewOutput.HasError = true;
 | ||
|                        importPreviewOutput.Results.Add((row++, false, ex.Message));
 | ||
|                        return;
 | ||
|                    }
 | ||
|                });
 | ||
| 
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         return ImportPreviews;
 | ||
|     }
 | ||
| 
 | ||
|     /// <inheritdoc/>
 | ||
|     [OperDesc("导入采集设备表", IsRecordPar = false)]
 | ||
|     public async Task ImportAsync(Dictionary<string, ImportPreviewOutputBase> input)
 | ||
|     {
 | ||
|         var collectDevices = new List<CollectDevice>();
 | ||
|         foreach (var item in input)
 | ||
|         {
 | ||
|             if (item.Key == ExportHelpers.CollectDeviceSheetName)
 | ||
|             {
 | ||
|                 var collectDeviceImports = ((ImportPreviewOutput<CollectDevice>)item.Value).Data;
 | ||
|                 collectDevices = collectDeviceImports.Values.Adapt<List<CollectDevice>>();
 | ||
|                 break;
 | ||
|             }
 | ||
|         }
 | ||
|         await Context.Storageable(collectDevices).ExecuteCommandAsync();
 | ||
|         CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_CollectDevice);//cache删除
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     #endregion
 | ||
| } | 
