添加api接口

This commit is contained in:
Diego
2025-09-01 16:00:53 +08:00
parent 4539d8d198
commit d1c46f51a6
23 changed files with 983 additions and 168 deletions

View File

@@ -30,9 +30,27 @@ public class ImportPreviewOutputBase
/// <summary>
/// 返回状态
/// </summary>
public ConcurrentList<(int Row, bool Success, string? ErrorMessage)> Results { get; set; } = new();
public ConcurrentList<ImportPreviewResult> Results { get; set; } = new();
}
public class ImportPreviewResult
{
public ImportPreviewResult()
{
}
public ImportPreviewResult(int row, bool success, string error)
{
this.Row = row;
this.Success = success;
this.ErrorMessage = error;
}
public int Row { get; set; }
public bool Success { get; set; }
public string? ErrorMessage { get; set; }
}
/// <summary>
/// 导入预览
/// </summary>

View File

@@ -9,6 +9,7 @@
// ------------------------------------------------------------------------------
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
namespace ThingsGateway.DB;
@@ -41,4 +42,31 @@ public static class FileExtensions
}
return fileName;
}
/// <summary>
/// 存储本地文件
/// </summary>
/// <param name="pPath">存储的第一层目录</param>
/// <param name="file"></param>
/// <returns>文件全路径</returns>
public static async Task<string> StorageLocal(this IFormFile file, string pPath = "imports")
{
string uploadFileFolder = App.WebHostEnvironment?.WebRootPath ?? "wwwroot"!;//赋值路径
var now = CommonUtils.GetSingleId();
var filePath = Path.Combine(uploadFileFolder, pPath);
if (!Directory.Exists(filePath))//如果不存在就创建文件夹
Directory.CreateDirectory(filePath);
//var fileSuffix = Path.GetExtension(file.Name).ToLower();// 文件后缀
var fileObjectName = $"{now}{file.Name}";//存储后的文件名
var fileName = Path.Combine(filePath, fileObjectName);//获取文件全路径
fileName = fileName.Replace("\\", "/");//格式化一系
//存储文件
using (var stream = File.Create(Path.Combine(filePath, fileObjectName)))
{
await file.CopyToAsync(stream).ConfigureAwait(false);
}
return fileName;
}
}

View File

@@ -254,6 +254,8 @@ public static class SpecificationDocumentBuilder
/// <param name="configure">自定义配置</param>
internal static void BuildGen(SwaggerGenOptions swaggerGenOptions, Action<SwaggerGenOptions> configure = null)
{
// 创建分组文档
CreateSwaggerDocs(swaggerGenOptions);
@@ -411,7 +413,7 @@ public static class SpecificationDocumentBuilder
// 本地函数
static string DefaultSchemaIdSelector(Type modelType)
{
var modelName = modelType.Name;
var modelName = modelType.FullName;
// 处理泛型类型问题
if (modelType.IsConstructedGenericType)

View File

@@ -0,0 +1,716 @@
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ThingsGateway.Authentication;
using TouchSocket.Core;
using TouchSocket.Rpc;
namespace ThingsGateway.Gateway.Application;
[ApiDescriptionSettings("ThingsGateway.OpenApi", Order = 200)]
[Route("openApi/management/[action]")]
[RolePermission]
[RequestAudit]
[ApiController]
[Authorize(AuthenticationSchemes = "Bearer")]
[TouchSocket.WebApi.Router("/miniapi/management/[action]")]
[TouchSocket.WebApi.EnableCors("cors")]
public partial class ManagementController : ControllerBase, IRpcServer
{
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<BackendLog>> BackendLogPageAsync(QueryPageOptions option) => App.GetService<IBackendLogService>().BackendLogPageAsync(option);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<List<BackendLogDayStatisticsOutput>> BackendLogStatisticsByDayAsync(int day) => App.GetService<IBackendLogService>().BackendLogStatisticsByDayAsync(day);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> BatchEditChannelAsync([FromBody] BatchEditChannelRequest request) =>
App.GetService<IChannelPageService>()
.BatchEditChannelAsync(request.Models, request.OldModel, request.Model, request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> BatchEditDeviceAsync([FromBody] BatchEditDeviceRequest request) =>
App.GetService<IDevicePageService>()
.BatchEditDeviceAsync(request.Models, request.OldModel, request.Model, request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> BatchEditVariableAsync([FromBody] BatchEditVariableRequest request) =>
App.GetService<IVariablePageService>()
.BatchEditVariableAsync(request.Models, request.OldModel, request.Model, request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> BatchSaveVariableAsync([FromBody] BatchSaveVariableRequest request) =>
App.GetService<IVariablePageService>()
.BatchSaveVariableAsync(request.Input, request.Type, request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<LogLevel> ChannelLogLevelAsync(long id) =>
App.GetService<IChannelPageService>().ChannelLogLevelAsync(id);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> ClearChannelAsync(bool restart) =>
App.GetService<IChannelPageService>().ClearChannelAsync(restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> ClearDeviceAsync(bool restart) =>
App.GetService<IDevicePageService>().ClearDeviceAsync(restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task ClearRulesAsync() => App.GetService<IRulesService>().ClearRulesAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> ClearVariableAsync(bool restart) =>
App.GetService<IVariablePageService>().ClearVariableAsync(restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task CopyChannelAsync([FromBody] CopyChannelRequest request) =>
App.GetService<IChannelPageService>()
.CopyChannelAsync(request.CopyCount,
request.CopyChannelNamePrefix,
request.CopyChannelNameSuffixNumber,
request.CopyDeviceNamePrefix,
request.CopyDeviceNameSuffixNumber,
request.ChannelId,
request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task CopyDeviceAsync([FromBody] CopyDeviceRequest request) =>
App.GetService<IDevicePageService>()
.CopyDeviceAsync(request.CopyCount,
request.CopyDeviceNamePrefix,
request.CopyDeviceNameSuffixNumber,
request.DeviceId,
request.AutoRestartThread);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task CopyVariableAsync([FromBody] CopyVariableRequest request) =>
App.GetService<IVariablePageService>()
.CopyVariableAsync(request.Model,
request.CopyCount,
request.CopyVariableNamePrefix,
request.CopyVariableNameSuffixNumber,
request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task DeleteBackendLogAsync() => App.GetService<IBackendLogService>().DeleteBackendLogAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> DeleteChannelAsync([FromBody] DeleteRequest request) =>
App.GetService<IChannelPageService>().DeleteChannelAsync(request.Ids, request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> DeleteDeviceAsync([FromBody] DeleteRequest request) =>
App.GetService<IDevicePageService>().DeleteDeviceAsync(request.Ids, request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> DeleteVariableAsync([FromBody] DeleteRequest request) =>
App.GetService<IVariablePageService>().DeleteVariableAsync(request.Ids, request.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task DeleteRpcLogAsync() => App.GetService<IRpcLogService>().DeleteRpcLogAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task DeleteRuleRuntimesAsync(List<long> ids) => App.GetService<IRulesEngineHostedService>().DeleteRuleRuntimesAsync(ids);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> DeleteRulesAsync(List<long> ids) => App.GetService<IRulesService>().DeleteRulesAsync(ids);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<LogLevel> DeviceLogLevelAsync(long id) =>
App.GetService<IDevicePageService>().DeviceLogLevelAsync(id);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task DeviceRedundantThreadAsync(long id) =>
App.GetService<IDevicePageService>().DeviceRedundantThreadAsync(id);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task EditRedundancyOptionAsync(RedundancyOptions input) => App.GetService<IRedundancyService>().EditRedundancyOptionAsync(input);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task EditRuleRuntimesAsync(Rules rules) => App.GetService<IRulesEngineHostedService>().EditRuleRuntimesAsync(rules);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<USheetDatas> ExportChannelAsync(List<Channel> channels) =>
App.GetService<IChannelPageService>().ExportChannelAsync(channels);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<string> ExportChannelFileAsync(GatewayExportFilter exportFilter) =>
App.GetService<IChannelPageService>().ExportChannelFileAsync(exportFilter);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<USheetDatas> ExportDeviceAsync(List<Device> devices) =>
App.GetService<IDevicePageService>().ExportDeviceAsync(devices);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<string> ExportDeviceFileAsync(GatewayExportFilter exportFilter) =>
App.GetService<IDevicePageService>().ExportDeviceFileAsync(exportFilter);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<USheetDatas> ExportVariableAsync(List<Variable> models, string? sortName, SortOrder sortOrder) =>
App.GetService<IVariablePageService>().ExportVariableAsync(models, sortName, sortOrder);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<string> ExportVariableFileAsync(GatewayExportFilter exportFilter) => App.GetService<IVariablePageService>().ExportVariableFileAsync(exportFilter);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<List<Channel>> GetChannelListAsync([FromBody] GetListRequest<QueryPageOptions> request) =>
App.GetService<IChannelPageService>().GetChannelListAsync(request.Options, request.Max);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<List<Device>> GetDeviceListAsync([FromBody] GetListRequest<QueryPageOptions> request) =>
App.GetService<IDevicePageService>().GetDeviceListAsync(request.Options, request.Max);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<List<Variable>> GetVariableListAsync([FromBody] GetListRequest<QueryPageOptions> request) =>
App.GetService<IVariablePageService>().GetVariableListAsync(request.Options, request.Max);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<List<Rules>> GetAllRulesAsync() => App.GetService<IRulesService>().GetAllRulesAsync();
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<string> GetChannelNameAsync(long id) =>
App.GetService<IChannelPageService>().GetChannelNameAsync(id);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<IEnumerable<SelectedItem>> GetCurrentUserDeviceSelectedItemsAsync(string searchText, int startIndex, int count) => App.GetService<IGlobalDataService>().GetCurrentUserDeviceSelectedItemsAsync(searchText, startIndex, count);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<QueryData<SelectedItem>> GetCurrentUserDeviceVariableSelectedItemsAsync(string deviceText, string searchText, int startIndex, int count) => App.GetService<IGlobalDataService>().GetCurrentUserDeviceVariableSelectedItemsAsync(deviceText, searchText, startIndex, count);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<IEnumerable<AlarmVariable>> GetCurrentUserRealAlarmVariablesAsync() => App.GetService<IRealAlarmService>().GetCurrentUserRealAlarmVariablesAsync();
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<Dictionary<long, Tuple<string, string>>> GetDeviceIdNamesAsync() => App.GetService<IDevicePageService>().GetDeviceIdNamesAsync();
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<string> GetDeviceNameAsync(long redundantDeviceId) =>
App.GetService<IDevicePageService>().GetDeviceNameAsync(redundantDeviceId);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<string> GetDevicePluginNameAsync(long id) =>
App.GetService<IDevicePageService>().GetDevicePluginNameAsync(id);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<OperResult<List<string>>> GetLogFilesAsync(string directoryPath) => App.GetService<ITextFileReadService>().GetLogFilesAsync(directoryPath);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<List<BackendLog>> GetNewBackendLogAsync() => App.GetService<IBackendLogService>().GetNewBackendLogAsync();
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<List<RpcLog>> GetNewRpcLogAsync() => App.GetService<IRpcLogService>().GetNewRpcLogAsync();
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<string> GetPluginNameAsync(long channelId) => App.GetService<IChannelPageService>().GetPluginNameAsync(channelId);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<List<PluginInfo>> GetPluginsAsync(PluginTypeEnum? pluginType = null) => App.GetService<IPluginPageService>().GetPluginsAsync(pluginType);
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<RedundancyOptions> GetRedundancyAsync() => App.GetService<IRedundancyService>().GetRedundancyAsync();
[HttpGet]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
public Task<Rules> GetRuleRuntimesAsync(long rulesId) => App.GetService<IRulesEngineHostedService>().GetRuleRuntimesAsync(rulesId);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task ImportChannelDataAsync([FromBody] ImportChannelInput input) =>
App.GetService<IChannelPageService>().ImportChannelAsync(input.UpData, input.InsertData, input.Restart);
[HttpPost]
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportChannelAsync([FromForm] ImportRequest request)
{
return (await App.GetService<IChannelRuntimeService>().ImportChannelAsync(request.File, request.Restart).ConfigureAwait(false)).AdaptImportPreviewOutputBases();
}
[ApiExplorerSettings(IgnoreApi = true)]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
[TouchSocket.WebApi.Router("/miniapi/management/ImportChannel")]
public async Task<Dictionary<string, ImportPreviewOutputBase>> TSImportChannelAsync(TouchSocket.WebApi.IWebApiCallContext callContext)
{
var path = await callContext.HttpContext.Request.StorageLocalExcel().ConfigureAwait(false);
return (await GlobalData.ChannelRuntimeService.ImportChannelFileAsync(path, true).ConfigureAwait(false)).AdaptImportPreviewOutputBases(); ;
}
[ApiExplorerSettings(IgnoreApi = true)]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
[TouchSocket.WebApi.Router("/miniapi/management/ImportDevice")]
public async Task<Dictionary<string, ImportPreviewOutputBase>> TSImportDeviceAsync(TouchSocket.WebApi.IWebApiCallContext callContext)
{
var path = await callContext.HttpContext.Request.StorageLocalExcel().ConfigureAwait(false);
return (await GlobalData.DeviceRuntimeService.ImportDeviceFileAsync(path, true).ConfigureAwait(false)).AdaptImportPreviewOutputBases(); ;
}
[ApiExplorerSettings(IgnoreApi = true)]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
[TouchSocket.WebApi.Router("/miniapi/management/ImportVariable")]
public async Task<Dictionary<string, ImportPreviewOutputBase>> TSImportVariableAsync(TouchSocket.WebApi.IWebApiCallContext callContext)
{
var path = await callContext.HttpContext.Request.StorageLocalExcel().ConfigureAwait(false);
return (await GlobalData.VariableRuntimeService.ImportVariableFileAsync(path, true).ConfigureAwait(false)).AdaptImportPreviewOutputBases();
}
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportChannelUSheetDatasAsync([FromBody] ImportUSheetInput input)
{
return (await App.GetService<IChannelPageService>().ImportChannelUSheetDatasAsync(input.Input, input.Restart).ConfigureAwait(false)).AdaptImportPreviewOutputBases();
}
[HttpPost]
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportDeviceAsync([FromForm] ImportRequest request)
{
return (await App.GetService<IDeviceRuntimeService>().ImportDeviceAsync(request.File, request.Restart).ConfigureAwait(false)).AdaptImportPreviewOutputBases();
}
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportDeviceUSheetDatasAsync([FromBody] ImportUSheetInput input)
{
return (await App.GetService<IDevicePageService>().ImportDeviceUSheetDatasAsync(input.Input, input.Restart).ConfigureAwait(false)).AdaptImportPreviewOutputBases();
}
[HttpPost]
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableAsync([FromForm] ImportRequest request)
{
return (await App.GetService<IVariableRuntimeService>().ImportVariableAsync(request.File, request.Restart).ConfigureAwait(false)).AdaptImportPreviewOutputBases();
}
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableUSheetDatasAsync([FromBody] ImportUSheetInput input)
{
return (await App.GetService<IVariablePageService>().ImportVariableUSheetDatasAsync(input.Input, input.Restart).ConfigureAwait(false)).AdaptImportPreviewOutputBases();
}
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task InsertTestDataAsync([FromBody] InsertTestDataInput input) =>
App.GetService<IVariablePageService>().InsertTestDataAsync(input.TestVariableCount, input.TestDeviceCount, input.SlaveUrl, input.BusinessEnable, input.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> IsRedundantDeviceAsync(long id) =>
App.GetService<IDevicePageService>().IsRedundantDeviceAsync(id);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<OperResult<List<LogData>>> LastLogDataAsync([FromBody] LastLogDataInput input) =>
App.GetService<ITextFileReadService>().LastLogDataAsync(input.File, input.LineCount);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<ChannelRuntime>> OnChannelQueryAsync([FromBody] QueryPageOptions options) =>
App.GetService<IChannelPageService>().OnChannelQueryAsync(options);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<SelectedItem>> OnChannelSelectedItemQueryAsync([FromBody] VirtualizeQueryOption option) =>
App.GetService<IChannelPageService>().OnChannelSelectedItemQueryAsync(option);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<DeviceRuntime>> OnDeviceQueryAsync([FromBody] QueryPageOptions options) =>
App.GetService<IDevicePageService>().OnDeviceQueryAsync(options);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<SelectedItem>> OnDeviceSelectedItemQueryAsync([FromBody] OnDeviceSelectedItemQueryInput input) =>
App.GetService<IDevicePageService>().OnDeviceSelectedItemQueryAsync(input.Option, input.IsCollect);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<SelectedItem>> OnRedundantDevicesQueryAsync([FromBody] OnRedundantDevicesQueryInput input) =>
App.GetService<IDevicePageService>().OnRedundantDevicesQueryAsync(input.Option, input.DeviceId, input.ChannelId);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<VariableRuntime>> OnVariableQueryAsync([FromBody] QueryPageOptions options) =>
App.GetService<IVariablePageService>().OnVariableQueryAsync(options);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<OperResult<object>> OnWriteVariableAsync(long id, string writeData) =>
App.GetService<IVariablePageService>().OnWriteVariableAsync(id, writeData);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task PauseThreadAsync(long id) =>
App.GetService<IDevicePageService>().PauseThreadAsync(id);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<PluginInfo>> PluginPageAsync([FromBody] PluginQueryPageOptions options) =>
App.GetService<IPluginPageService>().PluginPageAsync(options.Options, options.PluginType);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task RedundancyForcedSync() => App.GetService<IRedundancyHostedService>().RedundancyForcedSync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<LogLevel> RedundancyLogLevelAsync() => App.GetService<IRedundancyHostedService>().RedundancyLogLevelAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<string> RedundancyLogPathAsync() => App.GetService<IRedundancyHostedService>().RedundancyLogPathAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task ReloadPluginAsync() => App.GetService<IPluginPageService>().ReloadPluginAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task RestartChannelAsync(long channelId) =>
App.GetService<IChannelPageService>().RestartChannelAsync(channelId);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task RestartChannelsAsync() =>
App.GetService<IChannelPageService>().RestartChannelsAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task RestartDeviceAsync(long id, bool deleteCache) =>
App.GetService<IDevicePageService>().RestartDeviceAsync(id, deleteCache);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task RestartServerAsync() => App.GetService<IRestartService>().RestartServerAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<RpcLog>> RpcLogPageAsync([FromBody] QueryPageOptions option) =>
App.GetService<IRpcLogService>().RpcLogPageAsync(option);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<List<RpcLogDayStatisticsOutput>> RpcLogStatisticsByDayAsync(int day) =>
App.GetService<IRpcLogService>().RpcLogStatisticsByDayAsync(day);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<TouchSocket.Core.LogLevel> RulesLogLevelAsync(long rulesId) =>
App.GetService<IRulesEngineHostedService>().RulesLogLevelAsync(rulesId);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<string> RulesLogPathAsync(long rulesId) =>
App.GetService<IRulesEngineHostedService>().RulesLogPathAsync(rulesId);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<QueryData<Rules>> RulesPageAsync([FromBody] KVQueryPageOptions option) =>
App.GetService<IRulesService>().RulesPageAsync(option.Options, option.FilterKeyValueAction);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> SaveChannelAsync([FromBody] SaveChannelInput input) =>
App.GetService<IChannelPageService>().SaveChannelAsync(input.Input, input.Type, input.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> SaveDeviceAsync([FromBody] SaveDeviceInput input) =>
App.GetService<IDevicePageService>().SaveDeviceAsync(input.Input, input.Type, input.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task SavePluginByPathAsync([FromBody] PluginAddPathInput plugin) =>
App.GetService<IPluginPageService>().SavePluginByPathAsync(plugin);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> SaveRulesAsync([FromBody] Rules input, ItemChangedType type) =>
App.GetService<IRulesService>().SaveRulesAsync(input, type);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> SaveVariableAsync([FromBody] SaveVariableInput input) =>
App.GetService<IVariablePageService>().SaveVariableAsync(input.Input, input.Type, input.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task SetChannelLogLevelAsync([FromBody] SetChannelLogLevelInput input) =>
App.GetService<IChannelPageService>().SetChannelLogLevelAsync(input.Id, input.LogLevel);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task SetDeviceLogLevelAsync([FromBody] SetDeviceLogLevelInput input) =>
App.GetService<IDevicePageService>().SetDeviceLogLevelAsync(input.Id, input.LogLevel);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task SetRedundancyLogLevelAsync(LogLevel logLevel) =>
App.GetService<IRedundancyHostedService>().SetRedundancyLogLevelAsync(logLevel);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task SetRulesLogLevelAsync([FromBody] SetRulesLogLevelInput input) =>
App.GetService<IRulesEngineHostedService>().SetRulesLogLevelAsync(input.RulesId, input.LogLevel);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> StartBusinessChannelEnableAsync() => App.GetService<IChannelEnableService>().StartBusinessChannelEnableAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> StartCollectChannelEnableAsync() => App.GetService<IChannelEnableService>().StartCollectChannelEnableAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task StartRedundancyTaskAsync() => App.GetService<IRedundancyHostedService>().StartRedundancyTaskAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task StopRedundancyTaskAsync() => App.GetService<IRedundancyHostedService>().StopRedundancyTaskAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<AuthorizeInfo> TryAuthorizeAsync(string password) => App.GetService<IAuthenticationService>().TryAuthorizeAsync(password);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<AuthorizeInfo> TryGetAuthorizeInfoAsync() => App.GetService<IAuthenticationService>().TryGetAuthorizeInfoAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task UnAuthorizeAsync() => App.GetService<IAuthenticationService>().UnAuthorizeAsync();
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<string> UUIDAsync() => App.GetService<IAuthenticationService>().UUIDAsync();
}
// 定义请求 DTO
public class BatchEditChannelRequest
{
public List<Channel> Models { get; set; }
public Channel OldModel { get; set; }
public Channel Model { get; set; }
public bool Restart { get; set; }
}
public class BatchEditDeviceRequest
{
public List<Device> Models { get; set; }
public Device OldModel { get; set; }
public Device Model { get; set; }
public bool Restart { get; set; }
}
public class BatchEditVariableRequest
{
public List<Variable> Models { get; set; }
public Variable OldModel { get; set; }
public Variable Model { get; set; }
public bool Restart { get; set; }
}
public class BatchSaveVariableRequest
{
public List<Variable> Input { get; set; }
public ItemChangedType Type { get; set; }
public bool Restart { get; set; }
}
public class CopyChannelRequest
{
public int CopyCount { get; set; }
public string CopyChannelNamePrefix { get; set; }
public int CopyChannelNameSuffixNumber { get; set; }
public string CopyDeviceNamePrefix { get; set; }
public int CopyDeviceNameSuffixNumber { get; set; }
public long ChannelId { get; set; }
public bool Restart { get; set; }
}
public class CopyDeviceRequest
{
public int CopyCount { get; set; }
public string CopyDeviceNamePrefix { get; set; }
public int CopyDeviceNameSuffixNumber { get; set; }
public long DeviceId { get; set; }
public bool AutoRestartThread { get; set; }
}
public class CopyVariableRequest
{
public List<Variable> Model { get; set; }
public int CopyCount { get; set; }
public string CopyVariableNamePrefix { get; set; }
public int CopyVariableNameSuffixNumber { get; set; }
public bool Restart { get; set; }
}
public class DeleteRequest
{
public List<long> Ids { get; set; }
public bool Restart { get; set; }
}
public class GetListRequest<TOptions>
{
public TOptions Options { get; set; }
public int Max { get; set; }
}
public class ImportChannelInput
{
public List<Channel> UpData { get; set; }
public List<Channel> InsertData { get; set; }
public bool Restart { get; set; }
}
public class ImportFileInput
{
public bool Restart { get; set; }
}
public class ImportUSheetInput
{
public USheetDatas Input { get; set; }
public bool Restart { get; set; }
}
public class InsertTestDataInput
{
public int TestVariableCount { get; set; }
public int TestDeviceCount { get; set; }
public string SlaveUrl { get; set; }
public bool BusinessEnable { get; set; }
public bool Restart { get; set; }
}
public class LastLogDataInput
{
public string File { get; set; }
public int LineCount { get; set; } = 200;
}
public class OnDeviceSelectedItemQueryInput
{
public VirtualizeQueryOption Option { get; set; }
public bool IsCollect { get; set; }
}
public class OnRedundantDevicesQueryInput
{
public VirtualizeQueryOption Option { get; set; }
public long DeviceId { get; set; }
public long ChannelId { get; set; }
}
public class SaveChannelInput
{
public Channel Input { get; set; }
public ItemChangedType Type { get; set; }
public bool Restart { get; set; }
}
public class SaveDeviceInput
{
public Device Input { get; set; }
public ItemChangedType Type { get; set; }
public bool Restart { get; set; }
}
public class SaveVariableInput
{
public Variable Input { get; set; }
public ItemChangedType Type { get; set; }
public bool Restart { get; set; }
}
public class SetChannelLogLevelInput
{
public long Id { get; set; }
public LogLevel LogLevel { get; set; }
}
public class SetDeviceLogLevelInput
{
public long Id { get; set; }
public LogLevel LogLevel { get; set; }
}
public class SetRulesLogLevelInput
{
public long RulesId { get; set; }
public TouchSocket.Core.LogLevel LogLevel { get; set; }
}
public class ImportRequest
{
public IFormFile File { get; set; }
public bool Restart { get; set; }
}
public class PluginQueryPageOptions
{
public QueryPageOptions Options { get; set; }
public PluginTypeEnum PluginType { get; set; }
}
public class KVQueryPageOptions
{
public QueryPageOptions Options { get; set; }
public FilterKeyValueAction FilterKeyValueAction { get; set; }
}

View File

@@ -10,8 +10,6 @@
using BootstrapBlazor.Components;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace ThingsGateway.Gateway.Application;
/// <summary>
@@ -35,7 +33,7 @@ public class BackendLog : PrimaryIdEntity
/// </summary>
[SugarColumn(ColumnDescription = "日志级别", IsNullable = false)]
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
public LogLevel LogLevel { get; set; }
public Microsoft.Extensions.Logging.LogLevel LogLevel { get; set; }
/// <summary>
/// 日志来源

View File

@@ -67,4 +67,9 @@ public static partial class GatewayMapper
public static partial Device AdaptDevice(this Device src);
public static partial Variable AdaptVariable(this Variable src);
public static partial List<PluginInfo> AdaptListPluginInfo(this List<PluginInfo> src);
public static partial Dictionary<string, ImportPreviewOutputBase> AdaptImportPreviewOutputBases(this Dictionary<string, ImportPreviewOutputBase> src);
}

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using ThingsGateway.Extension.Generic;
@@ -401,6 +402,33 @@ public class ChannelRuntimeService : IChannelRuntimeService
}
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportChannelAsync(IFormFile file, bool restart)
{
try
{
await WaitLock.WaitAsync().ConfigureAwait(false);
var data = await GlobalData.ChannelService.PreviewAsync(file).ConfigureAwait(false);
if (data.Any(a => a.Value.HasError)) return data;
var result = await GlobalData.ChannelService.ImportChannelAsync(data).ConfigureAwait(false);
var newChannelRuntimes = await RuntimeServiceHelper.GetNewChannelRuntimesAsync(result).ConfigureAwait(false);
RuntimeServiceHelper.Init(newChannelRuntimes);
//根据条件重启通道线程
if (restart)
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
return data;
}
finally
{
WaitLock.Release();
}
}
public async Task ImportChannelAsync(Dictionary<string, ImportPreviewOutputBase> input, bool restart)
{

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using MiniExcelLibs;
@@ -409,8 +410,6 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
/// <inheritdoc/>
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile)
{
@@ -418,6 +417,13 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
return await PreviewAsync(path).ConfigureAwait(false);
}
/// <inheritdoc/>
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile)
{
var path = await browserFile.StorageLocal().ConfigureAwait(false);
return await PreviewAsync(path).ConfigureAwait(false);
}
/// <inheritdoc/>
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string path)
{
@@ -468,7 +474,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
if (channel == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, unportNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, unportNull));
return;
}
@@ -491,7 +497,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
if (stringBuilder.Length > 0)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, stringBuilder.ToString()));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, stringBuilder.ToString()));
return;
}
@@ -512,19 +518,19 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
if (channel.IsUp && ((dataScope != null && dataScope?.Count > 0 && !dataScope.Contains(channel.CreateOrgId)) || dataScope?.Count == 0 && channel.CreateUserId != UserManager.UserId))
{
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, "Operation not permitted"));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, "Operation not permitted"));
}
else
{
channels.Add(channel);
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), true, null));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), true, null));
}
return;
}
catch (Exception ex)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ex.Message));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ex.Message));
return;
}
});

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
namespace ThingsGateway.Gateway.Application;
@@ -38,7 +39,5 @@ public interface IChannelRuntimeService : IChannelPageService
Task<bool> CopyAsync(List<Channel> models, Dictionary<Device, List<Variable>> devices, bool restart);
Task<bool> UpdateAsync(List<Channel> models, List<Device> devices, List<Variable> variables, bool restart);
Task<bool> InsertAsync(List<Channel> models, List<Device> devices, List<Variable> variables, bool restart);
Task<Dictionary<string, ImportPreviewOutputBase>> ImportChannelAsync(IFormFile file, bool restart);
}

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using System.Linq.Expressions;
@@ -105,4 +106,5 @@ internal interface IChannelService
Task<HashSet<long>> ImportChannelAsync(List<Channel> upData, List<Channel> insertData);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string path);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile);
}

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using ThingsGateway.Extension.Generic;
@@ -356,6 +357,42 @@ public class DeviceRuntimeService : IDeviceRuntimeService
WaitLock.Release();
}
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportDeviceAsync(IFormFile file, bool restart)
{
try
{
await WaitLock.WaitAsync().ConfigureAwait(false);
var data = await GlobalData.DeviceService.PreviewAsync(file).ConfigureAwait(false);
if (data.Any(a => a.Value.HasError)) return data;
var deviceids = await GlobalData.DeviceService.ImportDeviceAsync(data).ConfigureAwait(false);
var newDeviceRuntimes = await RuntimeServiceHelper.GetNewDeviceRuntimesAsync(deviceids).ConfigureAwait(false);
if (restart)
{
var newDeciceIds = newDeviceRuntimes.Select(a => a.Id).ToHashSet();
await RuntimeServiceHelper.RemoveDeviceAsync(newDeciceIds).ConfigureAwait(false);
}
//批量修改之后,需要重新加载通道
RuntimeServiceHelper.Init(newDeviceRuntimes);
//根据条件重启通道线程
if (restart)
{
await RuntimeServiceHelper.RestartDeviceAsync(newDeviceRuntimes).ConfigureAwait(false);
}
return data;
}
finally
{
WaitLock.Release();
}
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportDeviceUSheetDatasAsync(USheetDatas input, bool restart)
{

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using MiniExcelLibs;
@@ -403,14 +404,20 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
return upData.Select(a => a.Id).Concat(insertData.Select(a => a.Id)).ToHashSet();
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile)
{
var path = await browserFile.StorageLocal().ConfigureAwait(false); // 上传文件并获取文件路径
return await PreviewAsync(path).ConfigureAwait(false);
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile)
{
var path = await browserFile.StorageLocal().ConfigureAwait(false); // 上传文件并获取文件路径
return await PreviewAsync(path).ConfigureAwait(false);
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string path)
{
@@ -495,7 +502,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (device == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ImportNullError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ImportNullError));
return;
}
@@ -512,7 +519,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
{
// 如果找不到对应的冗余设备,则添加错误信息到导入预览结果并返回
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, RedundantDeviceError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, RedundantDeviceError));
return;
}
}
@@ -522,7 +529,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (device.RedundantEnable)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, RedundantDeviceError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, RedundantDeviceError));
return;
}
}
@@ -536,7 +543,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
{
// 如果找不到对应的通道信息,则添加错误信息到导入预览结果并返回
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ChannelError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ChannelError));
return;
}
}
@@ -544,7 +551,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
{
// 如果未提供通道信息,则添加错误信息到导入预览结果并返回
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ChannelError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ChannelError));
return;
}
@@ -567,7 +574,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (stringBuilder.Length > 0)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, stringBuilder.ToString()));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, stringBuilder.ToString()));
return;
}
@@ -590,12 +597,12 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
// 将设备添加到设备列表中,并添加成功信息到导入预览结果
if (device.IsUp && ((dataScope != null && dataScope?.Count > 0 && !dataScope.Contains(device.CreateOrgId)) || dataScope?.Count == 0 && device.CreateUserId != UserManager.UserId))
{
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, "Operation not permitted"));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, "Operation not permitted"));
}
else
{
devices.Add(device);
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), true, null));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), true, null));
}
return;
}
@@ -603,7 +610,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
{
// 捕获异常并添加错误信息到导入预览结果
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ex.Message));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ex.Message));
return;
}
});
@@ -636,7 +643,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (driverPluginType == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, Localizer["NotNull", sheetName]));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, Localizer["NotNull", sheetName]));
return;
}
@@ -677,7 +684,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (propertys.Item1 == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, PluginNotNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, PluginNotNull));
continue;
}
@@ -685,7 +692,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (!item.TryGetValue(GatewayExportString.DeviceName, out var deviceName))
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, DeviceNotNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, DeviceNotNull));
continue;
}
@@ -697,7 +704,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (!hasDevice)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, Localizer["NotNull", value]));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, Localizer["NotNull", value]));
continue;
}
@@ -708,7 +715,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (pluginProp == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ImportNullError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ImportNullError));
return;
}
@@ -731,7 +738,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (stringBuilder.Length > 0)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, stringBuilder.ToString()));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, stringBuilder.ToString()));
return;
}
@@ -747,14 +754,14 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
// 更新设备导入预览数据中对应设备的属性信息,并添加成功信息到导入预览结果
deviceImportPreview.Data[value].DevicePropertys = devices;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), true, null));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), true, null));
continue;
}
catch (Exception ex)
{
// 捕获异常并添加错误信息到导入预览结果并返回
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ex.Message));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ex.Message));
return;
}
}

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
namespace ThingsGateway.Gateway.Application
{
@@ -24,5 +25,6 @@ namespace ThingsGateway.Gateway.Application
Task ImportDeviceAsync(Dictionary<string, ImportPreviewOutputBase> input, bool restart);
Task<bool> BatchSaveDeviceAsync(List<Device> input, ItemChangedType type, bool restart);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile);
Task<Dictionary<string, ImportPreviewOutputBase>> ImportDeviceAsync(IFormFile file, bool restart);
}
}

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using System.Collections.Concurrent;
using System.Linq.Expressions;
@@ -121,4 +122,5 @@ internal interface IDeviceService
Task UpdateLogAsync(long deviceId, TouchSocket.Core.LogLevel logLevel);
Task<HashSet<long>> ImportDeviceAsync(List<Device> upData, List<Device> insertData);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string path);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile);
}

View File

@@ -14,85 +14,66 @@ using ThingsGateway.Authentication;
using TouchSocket.Dmtp.Rpc;
using TouchSocket.Rpc;
using TouchSocket.WebApi;
namespace ThingsGateway.Gateway.Application;
#if Management
[GeneratorRpcProxy(GeneratorFlag = GeneratorFlag.ExtensionAsync)]
#endif
[TouchSocket.WebApi.Router("/miniapi/managementrpc/[action]")]
public interface IManagementRpcServer : IRpcServer
{
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<BackendLog>> BackendLogPageAsync(QueryPageOptions option);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<List<BackendLogDayStatisticsOutput>> BackendLogStatisticsByDayAsync(int day);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> BatchEditChannelAsync(List<Channel> models, Channel oldModel, Channel model, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> BatchEditDeviceAsync(List<Device> models, Device oldModel, Device model, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> BatchEditVariableAsync(List<Variable> models, Variable oldModel, Variable model, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> BatchSaveVariableAsync(List<Variable> input, ItemChangedType type, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<TouchSocket.Core.LogLevel> ChannelLogLevelAsync(long id);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> ClearChannelAsync(bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> ClearDeviceAsync(bool restart);
/// <summary>
/// 清除所有规则
/// </summary>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task ClearRulesAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> ClearVariableAsync(bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task CopyChannelAsync(int CopyCount, string CopyChannelNamePrefix, int CopyChannelNameSuffixNumber, string CopyDeviceNamePrefix, int CopyDeviceNameSuffixNumber, long channelId, bool AutoRestartThread);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task CopyDeviceAsync(int CopyCount, string CopyDeviceNamePrefix, int CopyDeviceNameSuffixNumber, long deviceId, bool AutoRestartThread);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task CopyVariableAsync(List<Variable> Model, int CopyCount, string CopyVariableNamePrefix, int CopyVariableNameSuffixNumber, bool AutoRestartThread);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task DeleteBackendLogAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> DeleteChannelAsync(List<long> ids, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> DeleteDeviceAsync(List<long> ids, bool restart);
/// <summary>
@@ -102,11 +83,9 @@ public interface IManagementRpcServer : IRpcServer
/// 调用此方法会删除 RpcLog 表中的所有记录。
/// </remarks>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task DeleteRpcLogAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task DeleteRuleRuntimesAsync(List<long> ids);
/// <summary>
@@ -114,19 +93,15 @@ public interface IManagementRpcServer : IRpcServer
/// </summary>
/// <param name="ids">待删除规则的ID列表</param>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> DeleteRulesAsync(List<long> ids);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> DeleteVariableAsync(List<long> ids, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<TouchSocket.Core.LogLevel> DeviceLogLevelAsync(long id);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task DeviceRedundantThreadAsync(long id);
/// <summary>
@@ -134,35 +109,27 @@ public interface IManagementRpcServer : IRpcServer
/// </summary>
/// <param name="input"></param>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task EditRedundancyOptionAsync(RedundancyOptions input);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task EditRuleRuntimesAsync(Rules rules);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<USheetDatas> ExportChannelAsync(List<Channel> channels);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<string> ExportChannelFileAsync(GatewayExportFilter exportFilter);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<USheetDatas> ExportDeviceAsync(List<Device> devices);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<string> ExportDeviceFileAsync(GatewayExportFilter exportFilter);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<USheetDatas> ExportVariableAsync(List<Variable> models, string? sortName, SortOrder sortOrder);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<string> ExportVariableFileAsync(GatewayExportFilter exportFilter);
/// <summary>
@@ -170,51 +137,39 @@ public interface IManagementRpcServer : IRpcServer
/// </summary>
/// <returns>规则列表</returns>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<List<Rules>> GetAllRulesAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<List<Channel>> GetChannelListAsync(QueryPageOptions options, int max = 0);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<string> GetChannelNameAsync(long channelId);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<IEnumerable<SelectedItem>> GetCurrentUserDeviceSelectedItemsAsync(string searchText, int startIndex, int count);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<QueryData<SelectedItem>> GetCurrentUserDeviceVariableSelectedItemsAsync(string deviceText, string searchText, int startIndex, int count);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<IEnumerable<AlarmVariable>> GetCurrentUserRealAlarmVariablesAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<Dictionary<long, Tuple<string, string>>> GetDeviceIdNamesAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<List<Device>> GetDeviceListAsync(QueryPageOptions option, int v);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<string> GetDeviceNameAsync(long redundantDeviceId);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<string> GetDevicePluginNameAsync(long id);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<OperResult<List<string>>> GetLogFilesAsync(string directoryPath);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<List<BackendLog>> GetNewBackendLogAsync();
/// <summary>
@@ -222,11 +177,9 @@ public interface IManagementRpcServer : IRpcServer
/// </summary>
/// <returns>最新的十条记录</returns>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<List<RpcLog>> GetNewRpcLogAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<string> GetPluginNameAsync(long channelId);
/// <summary>
@@ -235,140 +188,108 @@ public interface IManagementRpcServer : IRpcServer
/// <param name="pluginType"></param>
/// <returns></returns>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<List<PluginInfo>> GetPluginsAsync(PluginTypeEnum? pluginType = null);
/// <summary>
/// 获取冗余设置
/// </summary>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<RedundancyOptions> GetRedundancyAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<Rules> GetRuleRuntimesAsync(long rulesId);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<List<Variable>> GetVariableListAsync(QueryPageOptions option, int v);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task ImportChannelAsync(List<Channel> upData, List<Channel> insertData, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<Dictionary<string, ImportPreviewOutputBase>> ImportChannelFileAsync(string filePath, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<Dictionary<string, ImportPreviewOutputBase>> ImportChannelUSheetDatasAsync(USheetDatas input, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<Dictionary<string, ImportPreviewOutputBase>> ImportDeviceFileAsync(string filePath, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<Dictionary<string, ImportPreviewOutputBase>> ImportDeviceUSheetDatasAsync(USheetDatas input, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableFileAsync(string filePath, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableUSheetDatasAsync(USheetDatas data, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<bool> IsRedundantDeviceAsync(long id);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<OperResult<List<LogData>>> LastLogDataAsync(string file, int lineCount = 200);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<ChannelRuntime>> OnChannelQueryAsync(QueryPageOptions options);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<SelectedItem>> OnChannelSelectedItemQueryAsync(VirtualizeQueryOption option);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<DeviceRuntime>> OnDeviceQueryAsync(QueryPageOptions options);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<SelectedItem>> OnDeviceSelectedItemQueryAsync(VirtualizeQueryOption option, bool isCollect);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<SelectedItem>> OnRedundantDevicesQueryAsync(VirtualizeQueryOption option, long deviceId, long channelId);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<VariableRuntime>> OnVariableQueryAsync(QueryPageOptions options);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<OperResult<object>> OnWriteVariableAsync(long id, string writeData);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task PauseThreadAsync(long id);
/// <summary>
/// 分页显示插件
/// </summary>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<PluginInfo>> PluginPageAsync(QueryPageOptions options, PluginTypeEnum? pluginTypeEnum = null);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task RedundancyForcedSync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<TouchSocket.Core.LogLevel> RedundancyLogLevelAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<string> RedundancyLogPathAsync();
/// <summary>
/// 重载插件
/// </summary>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task ReloadPluginAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task RestartChannelAsync(long channelId);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task RestartChannelsAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task RestartDeviceAsync(long id, bool deleteCache);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task RestartServerAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<Dictionary<string, Dictionary<string, OperResult<object>>>> RpcAsync(ICallContext callContext, Dictionary<string, Dictionary<string, string>> deviceDatas);
/// <summary>
/// 分页查询 RpcLog 数据
@@ -376,7 +297,6 @@ public interface IManagementRpcServer : IRpcServer
/// <param name="option">查询选项</param>
/// <returns>查询到的数据</returns>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<RpcLog>> RpcLogPageAsync(QueryPageOptions option);
/// <summary>
@@ -385,14 +305,11 @@ public interface IManagementRpcServer : IRpcServer
/// <param name="day">统计的天数</param>
/// <returns>按天统计的结果列表</returns>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<List<RpcLogDayStatisticsOutput>> RpcLogStatisticsByDayAsync(int day);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<TouchSocket.Core.LogLevel> RulesLogLevelAsync(long rulesId);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<string> RulesLogPathAsync(long rulesId);
/// <summary>
@@ -401,15 +318,12 @@ public interface IManagementRpcServer : IRpcServer
/// <param name="option">查询条件</param>
/// <param name="filterKeyValueAction">查询条件</param>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<QueryData<Rules>> RulesPageAsync(QueryPageOptions option, FilterKeyValueAction filterKeyValueAction = null);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> SaveChannelAsync(Channel input, ItemChangedType type, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> SaveDeviceAsync(Device input, ItemChangedType type, bool restart);
/// <summary>
@@ -418,7 +332,6 @@ public interface IManagementRpcServer : IRpcServer
/// <param name="plugin"></param>
/// <returns></returns>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task SavePluginByPathAsync(PluginAddPathInput plugin);
/// <summary>
@@ -427,58 +340,44 @@ public interface IManagementRpcServer : IRpcServer
/// <param name="input">规则对象</param>
/// <param name="type">保存类型</param>
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> SaveRulesAsync(Rules input, ItemChangedType type);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> SaveVariableAsync(Variable input, ItemChangedType type, bool restart);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task SetChannelLogLevelAsync(long id, TouchSocket.Core.LogLevel logLevel);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task SetDeviceLogLevelAsync(long id, TouchSocket.Core.LogLevel logLevel);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task SetRedundancyLogLevelAsync(TouchSocket.Core.LogLevel logLevel);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task SetRulesLogLevelAsync(long rulesId, TouchSocket.Core.LogLevel logLevel);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> StartBusinessChannelEnableAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<bool> StartCollectChannelEnableAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task StartRedundancyTaskAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task StopRedundancyTaskAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task<AuthorizeInfo> TryAuthorizeAsync(string password);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<AuthorizeInfo> TryGetAuthorizeInfoAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task UnAuthorizeAsync();
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<string> UUIDAsync();
}

View File

@@ -11,22 +11,18 @@
using TouchSocket.Dmtp.Rpc;
using TouchSocket.Rpc;
using TouchSocket.WebApi;
namespace ThingsGateway.Gateway.Application;
#if Management
[GeneratorRpcProxy(GeneratorFlag = GeneratorFlag.ExtensionAsync)]
#endif
[TouchSocket.WebApi.Router("/miniapi/upgrade/[action]")]
public interface IUpgradeRpcServer : IRpcServer
{
[DmtpRpc]
[WebApi(Method = HttpMethodType.Post)]
Task UpgradeAsync(ICallContext callContext, UpdateZipFile updateZipFile);
[DmtpRpc]
[WebApi(Method = HttpMethodType.Get)]
Task<UpdateZipFileInput> GetUpdateZipFileInputAsync(ICallContext callContext);
Task<UpdateZipFileInput> GetUpdateZipFileInputAsync();
}

View File

@@ -14,7 +14,6 @@ using System.Runtime.InteropServices;
using ThingsGateway.NewLife;
using TouchSocket.Dmtp;
using TouchSocket.Dmtp.Rpc;
using TouchSocket.Rpc;
namespace ThingsGateway.Gateway.Application;
@@ -22,14 +21,12 @@ namespace ThingsGateway.Gateway.Application;
public partial class UpgradeRpcServer : IRpcServer, IUpgradeRpcServer
{
[DmtpRpc]
public async Task UpgradeAsync(ICallContext callContext, UpdateZipFile updateZipFile)
{
if (callContext.Caller is IDmtpActorObject dmtpActorObject)
await Update(dmtpActorObject.DmtpActor, updateZipFile).ConfigureAwait(false);
}
[DmtpRpc]
public Task<UpdateZipFileInput> GetUpdateZipFileInputAsync(ICallContext callContext)
public Task<UpdateZipFileInput> GetUpdateZipFileInputAsync()
{
return Task.FromResult(new UpdateZipFileInput()
{

View File

@@ -89,8 +89,8 @@ public partial class WebApiTask : AsyncDisposableObject
store.RegisterServer<RuntimeInfoController>();
store.RegisterServer<TestController>();
store.RegisterServer<IManagementRpcServer>(new ManagementRpcServer());
store.RegisterServer<IUpgradeRpcServer>(new UpgradeRpcServer());
store.RegisterServer<ManagementController>();
foreach (var type in App.EffectiveTypes.Where(p => typeof(IPluginRpcServer).IsAssignableFrom(p) && !p.IsAbstract && p.IsClass))
{

View File

@@ -9,6 +9,7 @@
// ------------------------------------------------------------------------------
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
namespace ThingsGateway.Gateway.Application
{
@@ -21,5 +22,6 @@ namespace ThingsGateway.Gateway.Application
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile);
Task<MemoryStream> ExportMemoryStream(List<Variable> data, string devName);
Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableAsync(IFormFile file, bool restart);
}
}

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using System.Collections.Concurrent;
using System.Reflection;
@@ -110,4 +111,5 @@ internal interface IVariableService
List<VariableRuntime> GetAllVariableRuntime();
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string filePath);
Task<HashSet<long>> ImportVariableAsync(List<Variable> upData, List<Variable> insertData);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile);
}

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using ThingsGateway.Extension.Generic;
@@ -311,6 +312,42 @@ public class VariableRuntimeService : IVariableRuntimeService
//WaitLock.Release();
}
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableAsync(IFormFile file, bool restart)
{
try
{
// await WaitLock.WaitAsync().ConfigureAwait(false);
var data = await GlobalData.VariableService.PreviewAsync(file).ConfigureAwait(false);
if (data.Any(a => a.Value.HasError)) return data;
var result = await GlobalData.VariableService.ImportVariableAsync(data).ConfigureAwait(false);
using var db = DbContext.GetDB<Variable>();
var newVariableRuntimes = (await db.Queryable<Variable>().Where(a => result.Contains(a.Id)).ToListAsync().ConfigureAwait(false)).AdaptListVariableRuntime();
var variableIds = newVariableRuntimes.Select(a => a.Id).ToHashSet();
ConcurrentHashSet<IDriver> changedDriver = new();
RuntimeServiceHelper.VariableRuntimesDispose(variableIds);
RuntimeServiceHelper.AddCollectChangedDriver(newVariableRuntimes, changedDriver);
RuntimeServiceHelper.AddBusinessChangedDriver(variableIds, changedDriver);
if (restart)
{
//根据条件重启通道线程
await RuntimeServiceHelper.ChangedDriverAsync(changedDriver, _logger).ConfigureAwait(false);
}
return data;
}
finally
{
//WaitLock.Release();
}
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableFileAsync(string filePath, bool restart)
{
try

View File

@@ -11,6 +11,7 @@
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using MiniExcelLibs;
@@ -588,7 +589,12 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
return await PreviewAsync(path).ConfigureAwait(false);
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile)
{
var path = await browserFile.StorageLocal().ConfigureAwait(false); // 上传文件并获取文件路径
return await PreviewAsync(path).ConfigureAwait(false);
}
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string path)
{
// 上传文件并获取文件路径
@@ -675,7 +681,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (deviceId == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, Localizer["NotNull", deviceName]));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, Localizer["NotNull", deviceName]));
return;
}
// 手动补录变量ID和设备ID
@@ -698,7 +704,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (stringBuilder.Length > 0)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, stringBuilder.ToString()));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, stringBuilder.ToString()));
return;
}
@@ -717,19 +723,19 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
}
if (device.IsUp && ((dataScope != null && dataScope?.Count > 0 && !dataScope.Contains(variable.CreateOrgId)) || dataScope?.Count == 0 && variable.CreateUserId != UserManager.UserId))
{
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, "Operation not permitted"));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, "Operation not permitted"));
}
else
{
variables.Add(variable);
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), true, null));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), true, null));
}
}
catch (Exception ex)
{
// 捕获异常并添加错误信息到导入预览结果
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ex.Message));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ex.Message));
}
});
@@ -764,7 +770,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (alarm == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ImportNullError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ImportNullError));
return;
}
@@ -776,13 +782,13 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (collectDevName == null || collectDevice == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, DeviceNotNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, DeviceNotNull));
return;
}
if (variableNameObj == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, VariableNotNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, VariableNotNull));
return;
}
@@ -805,7 +811,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (stringBuilder.Length > 0)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, stringBuilder.ToString()));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, stringBuilder.ToString()));
return;
}
@@ -815,12 +821,12 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (deviceImportPreview.Data.TryGetValue(collectDevice.Id.ToString(), out var deviceVariables) && deviceVariables.TryGetValue(variableName, out var deviceVariable))
{
deviceVariable.AlarmPropertys = alarm;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), true, null));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), true, null));
}
else
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, VariableNotNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, VariableNotNull));
return;
}
}
@@ -828,7 +834,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
{
// 捕获异常并添加错误信息到导入预览结果
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ex.Message));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ex.Message));
}
});
@@ -848,7 +854,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (driverPluginType == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, Localizer["NotNull", sheetName]));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, Localizer["NotNull", sheetName]));
return deviceImportPreview;
}
@@ -885,7 +891,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (propertys.Item3?.Count == null || propertys.Item1 == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ImportNullError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ImportNullError));
return;
}
@@ -896,7 +902,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (pluginProp == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ImportNullError));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ImportNullError));
return;
}
@@ -911,13 +917,13 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (businessDevName == null || businessDevice == null || collectDevName == null || collectDevice == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, DeviceNotNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, DeviceNotNull));
return;
}
if (variableNameObj == null)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, VariableNotNull));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, VariableNotNull));
return;
}
@@ -940,7 +946,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
if (stringBuilder.Length > 0)
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, stringBuilder.ToString()));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, stringBuilder.ToString()));
return;
}
@@ -961,12 +967,12 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
{
deviceVariable.VariablePropertys ??= new();
deviceVariable.VariablePropertys?.AddOrUpdate(businessDevice.Id, dependencyProperties);
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), true, null));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), true, null));
}
else
{
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, Localizer["VariableNotNull"]));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, Localizer["VariableNotNull"]));
return;
}
}
@@ -974,7 +980,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
{
// 捕获异常并添加错误信息到导入预览结果
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ex.Message));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ex.Message));
}
});
}
@@ -982,7 +988,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
{
// 捕获异常并添加错误信息到导入预览结果
importPreviewOutput.HasError = true;
importPreviewOutput.Results.Add((Interlocked.Increment(ref row), false, ex.Message));
importPreviewOutput.Results.Add(new(Interlocked.Increment(ref row), false, ex.Message));
}
}

View File

@@ -15,6 +15,32 @@ namespace ThingsGateway.Gateway.Application;
[ThingsGateway.DependencyInjection.SuppressSniffer]
public static class GatewayResourceUtil
{
/// <summary>
/// 存储本地文件
/// </summary>
/// <param name="pPath">存储的第一层目录</param>
/// <param name="file"></param>
/// <returns>文件全路径</returns>
public static async Task<string> StorageLocalExcel(this TouchSocket.Http.HttpRequest file, string pPath = "imports")
{
string uploadFileFolder = App.WebHostEnvironment?.WebRootPath ?? "wwwroot"!;//赋值路径
var now = CommonUtils.GetSingleId();
var filePath = Path.Combine(uploadFileFolder, pPath);
if (!Directory.Exists(filePath))//如果不存在就创建文件夹
Directory.CreateDirectory(filePath);
//var fileSuffix = Path.GetExtension(file.Name).ToLower();// 文件后缀
var fileObjectName = $"{now}.xlsx";//存储后的文件名
var fileName = Path.Combine(filePath, fileObjectName);//获取文件全路径
fileName = fileName.Replace("\\", "/");//格式化一系
//存储文件
using (var stream = File.Create(Path.Combine(filePath, fileObjectName)))
{
await file.ReadCopyToAsync(stream).ConfigureAwait(false);
}
return fileName;
}
/// <summary>
/// 构造选择项ID/Name
/// </summary>