更新版本

This commit is contained in:
Diego
2024-11-19 10:28:42 +08:00
parent cd497ab4dc
commit 91614772dc
13 changed files with 169 additions and 57 deletions

View File

@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<AdminVersion>7.2.0.11</AdminVersion>
<PluginVersion>9.0.2.11</PluginVersion>
<AdminVersion>7.2.0.17</AdminVersion>
<PluginVersion>9.0.2.12</PluginVersion>
<ProPluginVersion>9.0.2.18</ProPluginVersion>
</PropertyGroup>

View File

@@ -1,17 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)PackNuget.props" />
<Import Project="$(SolutionDir)FoundationVersion.props" />
<Import Project="$(SolutionDir)PackNuget.props" />
<Import Project="$(SolutionDir)FoundationVersion.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net9.0;net8.0;net6.0;</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net9.0;net8.0;net6.0;</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CS-Script" Version="4.8.19" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0'">
<PackageReference Include="CS-Script" Version="4.8.21" />
<ItemGroup>
<PackageReference Include="ThingsGateway.NewLife.X" Version="$(AdminVersion)" />
</ItemGroup>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'net8.0' AND '$(TargetFramework)' != 'net9.0'">
<PackageReference Include="CS-Script" Version="4.8.19" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ThingsGateway.NewLife.X" Version="$(AdminVersion)" />
</ItemGroup>
</Project>

View File

@@ -10,15 +10,88 @@
using BootstrapBlazor.Components;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace ThingsGateway.Gateway.Application;
/// <summary>
/// 查询条件实体类
/// </summary>
public class QueryPageOptionsDto
{
/// <summary>
/// 获得/设置 模糊查询关键字
/// </summary>
public string? SearchText { get; set; }
/// <summary>
/// 获得 排序字段名称 由 <see cref="Table{TItem}.SortName"/> 设置
/// </summary>
public string? SortName { get; set; }
/// <summary>
/// 获得 排序方式 由 <see cref="Table{TItem}.SortOrder"/> 设置
/// </summary>
public SortOrder SortOrder { get; set; }
/// <summary>
/// 获得/设置 多列排序集合 默认为 Empty 内部为 "Name" "Age desc" 由 <see cref="Table{TItem}.SortString"/> 设置
/// </summary>
public List<string> SortList { get; } = new(10);
/// <summary>
/// 获得/设置 自定义多列排序集合 默认为 Empty 内部为 "Name" "Age desc" 由 <see cref="Table{TItem}.AdvancedSortItems"/> 设置
/// </summary>
public List<string> AdvancedSortList { get; } = new(10);
/// <summary>
/// 获得 搜索条件绑定模型 未设置 <see cref="Table{TItem}.CustomerSearchModel"/> 时为 <see cref="Table{TItem}"/> 泛型模型
/// </summary>
public object? SearchModel { get; set; }
/// <summary>
/// 获得 当前页码 首页为 第一页
/// </summary>
public int PageIndex { get; set; } = 1;
/// <summary>
/// 获得 请求读取数据开始行 默认 0
/// </summary>
/// <remarks><see cref="Table{TItem}.ScrollMode"/> 开启虚拟滚动 <see cref="ScrollMode.Virtual"/> 时使用</remarks>
public int StartIndex { get; set; }
public int PageItems { get; set; } = 20;
/// <summary>
/// 获得 是否分页查询模式 默认为 false 由 <see cref="Table{TItem}.IsPagination"/> 设置
/// </summary>
public bool IsPage { get; set; }
/// <summary>
/// 获得 是否为虚拟滚动查询模式 默认为 false 由 <see cref="Table{TItem}.ScrollMode"/> 设置
/// </summary>
public bool IsVirtualScroll { get; set; }
/// <summary>
/// 获得 是否为首次查询 默认 false
/// </summary>
/// <remarks><see cref="Table{TItem}"/> 组件首次查询数据时为 true</remarks>
public bool IsFirstQuery { get; set; }
}
public class ExportDto
{
public QueryPageOptionsDto QueryPageOptions { get; set; } = new();
public FilterKeyValueAction FilterKeyValueAction { get; set; } = new();
}
/// <summary>
/// 导出文件
/// </summary>
[ApiDescriptionSettings(false)]
[Route("api/gatewayExport")]
[IgnoreRolePermission]
[Authorize]
[LoggingMonitor]
public class GatewayExportController : ControllerBase
{
@@ -27,7 +100,6 @@ public class GatewayExportController : ControllerBase
private readonly IVariableService _variableService;
private readonly IImportExportService _importExportService;
public GatewayExportController(
IChannelService channelService,
IDeviceService deviceService,
@@ -46,12 +118,12 @@ public class GatewayExportController : ControllerBase
/// 下载设备
/// </summary>
/// <returns></returns>
[HttpGet("businessdevice")]
public async Task<IActionResult> DownloadBusinessDeviceAsync([FromQuery] QueryPageOptions input)
[HttpPost("businessdevice")]
public async Task<IActionResult> DownloadBusinessDeviceAsync([FromBody] ExportDto input)
{
input.IsPage = false;
input.IsVirtualScroll = false;
var sheets = await _deviceService.ExportDeviceAsync(input, PluginTypeEnum.Business).ConfigureAwait(false);
input.QueryPageOptions.IsPage = false;
input.QueryPageOptions.IsVirtualScroll = false;
var sheets = await _deviceService.ExportDeviceAsync(input.QueryPageOptions.Adapt<QueryPageOptions>(), PluginTypeEnum.Business, input.FilterKeyValueAction).ConfigureAwait(false);
return await _importExportService.ExportAsync<Device>(sheets, "BusinessDevice", false).ConfigureAwait(false);
}
@@ -60,13 +132,13 @@ public class GatewayExportController : ControllerBase
/// 下载通道
/// </summary>
/// <returns></returns>
[HttpGet("channel")]
public async Task<IActionResult> DownloadChannelAsync([FromQuery] QueryPageOptions input)
[HttpPost("channel")]
public async Task<IActionResult> DownloadChannelAsync([FromBody] ExportDto input)
{
input.IsPage = false;
input.IsVirtualScroll = false;
input.QueryPageOptions.IsPage = false;
input.QueryPageOptions.IsVirtualScroll = false;
var sheets = await _channelService.ExportChannelAsync(input).ConfigureAwait(false);
var sheets = await _channelService.ExportChannelAsync(input.QueryPageOptions.Adapt<QueryPageOptions>(), input.FilterKeyValueAction).ConfigureAwait(false);
return await _importExportService.ExportAsync<Channel>(sheets, "Channel", false).ConfigureAwait(false);
}
@@ -74,13 +146,13 @@ public class GatewayExportController : ControllerBase
/// 下载设备
/// </summary>
/// <returns></returns>
[HttpGet("collectdevice")]
public async Task<IActionResult> DownloadCollectDeviceAsync([FromQuery] QueryPageOptions input)
[HttpPost("collectdevice")]
public async Task<IActionResult> DownloadCollectDeviceAsync([FromBody] ExportDto input)
{
input.IsPage = false;
input.IsVirtualScroll = false;
input.QueryPageOptions.IsPage = false;
input.QueryPageOptions.IsVirtualScroll = false;
var sheets = await _deviceService.ExportDeviceAsync(input, PluginTypeEnum.Collect).ConfigureAwait(false);
var sheets = await _deviceService.ExportDeviceAsync(input.QueryPageOptions.Adapt<QueryPageOptions>(), PluginTypeEnum.Collect, input.FilterKeyValueAction).ConfigureAwait(false);
return await _importExportService.ExportAsync<Device>(sheets, "CollectDevice", false).ConfigureAwait(false);
}
@@ -88,13 +160,13 @@ public class GatewayExportController : ControllerBase
/// 下载变量
/// </summary>
/// <returns></returns>
[HttpGet("variable")]
public async Task<IActionResult> DownloadVariableAsync([FromQuery] QueryPageOptions input)
[HttpPost("variable")]
public async Task<IActionResult> DownloadVariableAsync([FromBody] ExportDto input)
{
input.IsPage = false;
input.IsVirtualScroll = false;
input.QueryPageOptions.IsPage = false;
input.QueryPageOptions.IsVirtualScroll = false;
var sheets = await _variableService.ExportVariableAsync(input).ConfigureAwait(false);
var sheets = await _variableService.ExportVariableAsync(input.QueryPageOptions.Adapt<QueryPageOptions>(), input.FilterKeyValueAction).ConfigureAwait(false);
return await _importExportService.ExportAsync<Variable>(sheets, "Variable", false).ConfigureAwait(false);
}
}

View File

@@ -20,6 +20,7 @@
"SortCode": 0,
"ExtJson": null
},
{
"Id": 61100022003,
"ParentId": 6100001,
@@ -1007,6 +1008,27 @@
"SortCode": 102,
"ExtJson": null
},
{
"Id": 11000022001002,
"ParentId": 0,
"Module": 6,
"Title": "重启",
"Icon": null,
"Code": "System",
"Category": 2,
"Target": null,
"NavLinkMatch": null,
"Href": null,
"CreateTime": "5/11/2024 04:08:09.92",
"CreateUser": "SuperAdmin",
"CreateUserId": 212725263002001,
"IsDelete": "0",
"UpdateTime": "5/11/2024 04:28:42.83",
"UpdateUser": null,
"UpdateUserId": null,
"SortCode": null,
"ExtJson": null
},
{
"Id": 6100002,
"ParentId": 0,

View File

@@ -174,14 +174,15 @@ internal class ChannelService : BaseService<Channel>, IChannelService
/// 报表查询
/// </summary>
/// <param name="option">查询条件</param>
public async Task<QueryData<Channel>> PageAsync(QueryPageOptions option)
/// <param name="filterKeyValueAction">查询条件</param>
public async Task<QueryData<Channel>> PageAsync(QueryPageOptions option, FilterKeyValueAction filterKeyValueAction = null)
{
var dataScope = await SysUserService.GetCurrentUserDataScopeAsync();
return await QueryAsync(option, a => a
.WhereIF(!option.SearchText.IsNullOrWhiteSpace(), a => a.Name.Contains(option.SearchText!))
.WhereIF(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.CreateOrgId))//在指定机构列表查询
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
);
, filterKeyValueAction);
}
/// <summary>
@@ -273,9 +274,9 @@ internal class ChannelService : BaseService<Channel>, IChannelService
/// <inheritdoc/>
[OperDesc("ExportChannel", isRecordPar: false, localizerType: typeof(Channel))]
public async Task<Dictionary<string, object>> ExportChannelAsync(QueryPageOptions options)
public async Task<Dictionary<string, object>> ExportChannelAsync(QueryPageOptions options, FilterKeyValueAction filterKeyValueAction = null)
{
var data = await PageAsync(options).ConfigureAwait(false);
var data = await PageAsync(options, filterKeyValueAction).ConfigureAwait(false);
return ExportChannelCore(data.Items);
}

View File

@@ -48,7 +48,7 @@ public interface IChannelService
/// 导出通道为文件流结果
/// </summary>
/// <returns>文件流结果</returns>
Task<Dictionary<string, object>> ExportChannelAsync(QueryPageOptions options);
Task<Dictionary<string, object>> ExportChannelAsync(QueryPageOptions options, FilterKeyValueAction filterKeyValueAction = null);
/// <summary>
/// 导出通道为内存流
@@ -84,7 +84,8 @@ public interface IChannelService
/// 报表查询
/// </summary>
/// <param name="option">查询条件</param>
Task<QueryData<Channel>> PageAsync(QueryPageOptions option);
/// <param name="filterKeyValueAction">查询条件</param>
Task<QueryData<Channel>> PageAsync(QueryPageOptions option, FilterKeyValueAction filterKeyValueAction = null);
/// <summary>
/// API查询

View File

@@ -293,14 +293,15 @@ internal class DeviceService : BaseService<Device>, IDeviceService
/// </summary>
/// <param name="option">查询条件</param>
/// <param name="pluginType">查询条件</param>
public async Task<QueryData<Device>> PageAsync(QueryPageOptions option, PluginTypeEnum pluginType)
/// <param name="filterKeyValueAction">查询条件</param>
public async Task<QueryData<Device>> PageAsync(QueryPageOptions option, PluginTypeEnum pluginType, FilterKeyValueAction filterKeyValueAction = null)
{
var dataScope = await SysUserService.GetCurrentUserDataScopeAsync();
return await QueryAsync(option, a => a
.WhereIF(!option.SearchText.IsNullOrWhiteSpace(), a => a.Name.Contains(option.SearchText!)).Where(a => a.PluginType == pluginType)
.WhereIF(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.CreateOrgId))//在指定机构列表查询
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
);
, filterKeyValueAction);
}
@@ -372,10 +373,10 @@ internal class DeviceService : BaseService<Device>, IDeviceService
/// </summary>
/// <returns></returns>
[OperDesc("ExportDevice", isRecordPar: false, localizerType: typeof(Device))]
public async Task<Dictionary<string, object>> ExportDeviceAsync(QueryPageOptions options, PluginTypeEnum pluginType)
public async Task<Dictionary<string, object>> ExportDeviceAsync(QueryPageOptions options, PluginTypeEnum pluginType, FilterKeyValueAction filterKeyValueAction = null)
{
//导出
var data = await PageAsync(options, pluginType).ConfigureAwait(false);
var data = await PageAsync(options, pluginType, filterKeyValueAction).ConfigureAwait(false);
string fileName;
Dictionary<string, object> sheets;
ExportCore(data.Items, pluginType, out fileName, out sheets);

View File

@@ -64,7 +64,7 @@ public interface IDeviceService
/// 导出设备信息到文件流。
/// </summary>
/// <returns>导出的文件流</returns>
Task<Dictionary<string, object>> ExportDeviceAsync(QueryPageOptions options, PluginTypeEnum pluginType);
Task<Dictionary<string, object>> ExportDeviceAsync(QueryPageOptions options, PluginTypeEnum pluginType, FilterKeyValueAction filterKeyValueAction = null);
/// <summary>
/// 导出设备信息到内存流。
@@ -115,8 +115,9 @@ public interface IDeviceService
/// </summary>
/// <param name="option">查询条件</param>
/// <param name="pluginType">查询条件</param>
/// <param name="filterKeyValueAction">查询条件</param>
/// <returns>查询结果</returns>
Task<QueryData<Device>> PageAsync(QueryPageOptions option, PluginTypeEnum pluginType);
Task<QueryData<Device>> PageAsync(QueryPageOptions option, PluginTypeEnum pluginType, FilterKeyValueAction filterKeyValueAction = null);
/// <summary>
/// API查询

View File

@@ -10,10 +10,14 @@
using BootstrapBlazor.Components;
using Mapster;
using Microsoft.JSInterop;
using ThingsGateway.Extension;
using TouchSocket.Core;
namespace ThingsGateway.Gateway.Application;
internal class GatewayExportService : IGatewayExportService
@@ -30,7 +34,7 @@ internal class GatewayExportService : IGatewayExportService
await using var ajaxJS = await JSRuntime.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Razor/js/downloadFile.js");
string url = "api/gatewayExport/channel";
string fileName = DateTime.Now.ToFileDateTimeFormat();
await ajaxJS.InvokeVoidAsync("blazor_downloadFile", url, fileName, dtoObject);
await ajaxJS.InvokeVoidAsync("postJson_downloadFile", url, fileName, new ExportDto() { FilterKeyValueAction = dtoObject.ToFilter(), QueryPageOptions = dtoObject.Adapt<QueryPageOptionsDto>() }.ToJsonString());
}
public async Task OnDeviceExport(QueryPageOptions dtoObject, bool collect)
@@ -38,7 +42,7 @@ internal class GatewayExportService : IGatewayExportService
await using var ajaxJS = await JSRuntime.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Razor/js/downloadFile.js");
string url = collect ? "api/gatewayExport/collectdevice" : "api/gatewayExport/businessdevice";
string fileName = DateTime.Now.ToFileDateTimeFormat();
await ajaxJS.InvokeVoidAsync("blazor_downloadFile", url, fileName, dtoObject);
await ajaxJS.InvokeVoidAsync("postJson_downloadFile", url, fileName, new ExportDto() { FilterKeyValueAction = dtoObject.ToFilter(), QueryPageOptions = dtoObject.Adapt<QueryPageOptionsDto>() }.ToJsonString());
}
public async Task OnVariableExport(QueryPageOptions dtoObject)
@@ -46,6 +50,7 @@ internal class GatewayExportService : IGatewayExportService
await using var ajaxJS = await JSRuntime.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Razor/js/downloadFile.js");
string url = "api/gatewayExport/variable";
string fileName = DateTime.Now.ToFileDateTimeFormat();
await ajaxJS.InvokeVoidAsync("blazor_downloadFile", url, fileName, dtoObject);
await ajaxJS.InvokeVoidAsync("postJson_downloadFile", url, fileName, new ExportDto() { FilterKeyValueAction = dtoObject.ToFilter(), QueryPageOptions = dtoObject.Adapt<QueryPageOptionsDto>() }.ToJsonString());
}
}

View File

@@ -64,8 +64,7 @@ public interface IVariableService
/// <summary>
/// 异步导出变量数据到文件流中。
/// </summary>
/// <param name="options">查询分页选项。</param>
Task<Dictionary<string, object>> ExportVariableAsync(QueryPageOptions options);
Task<Dictionary<string, object>> ExportVariableAsync(QueryPageOptions options, FilterKeyValueAction filterKeyValueAction = null);
/// <summary>
/// 异步获取变量的运行时信息。

View File

@@ -358,9 +358,9 @@ internal class VariableService : BaseService<Variable>, IVariableService
/// 导出文件
/// </summary>
[OperDesc("ExportVariable", isRecordPar: false, localizerType: typeof(Variable))]
public async Task<Dictionary<string, object>> ExportVariableAsync(QueryPageOptions options)
public async Task<Dictionary<string, object>> ExportVariableAsync(QueryPageOptions options, FilterKeyValueAction filterKeyValueAction = null)
{
var data = (await QueryAsync(options).ConfigureAwait(false));
var data = (await QueryAsync(options, null, filterKeyValueAction).ConfigureAwait(false));
Dictionary<string, object> sheets = ExportCore(data.Items);
return sheets;
}

View File

@@ -98,8 +98,10 @@
</NotAuthorized>
</Layout>
<ThingsGateway.Gateway.Razor.QuickActions></ThingsGateway.Gateway.Razor.QuickActions>
@if(AppContext.IsHasButtonWithRole("", "重启"))
{
<ThingsGateway.Gateway.Razor.QuickActions/>
}
</div>

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>7.2.0.15</Version>
<Version>7.2.0.16</Version>
</PropertyGroup>
<ItemGroup>