Compare commits
85 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5b460e8fa2 | ||
![]() |
41087edf17 | ||
![]() |
2afcc38e38 | ||
![]() |
e59ccce25f | ||
![]() |
d7425890e8 | ||
![]() |
a989a837fb | ||
![]() |
db1221da50 | ||
![]() |
cf794569ed | ||
![]() |
51e5bbab0d | ||
![]() |
2c197ed2b2 | ||
![]() |
d8fc6665b3 | ||
![]() |
c671a79822 | ||
![]() |
9d93ce4c41 | ||
![]() |
a6d99fe227 | ||
![]() |
923b8bca31 | ||
![]() |
e2c30d1c88 | ||
![]() |
b6d9f2a04e | ||
![]() |
57306ea664 | ||
![]() |
cd7f3fd02f | ||
![]() |
0482e077a8 | ||
![]() |
5f986a45ca | ||
![]() |
ca7b49c0d5 | ||
![]() |
52dd555e6c | ||
![]() |
579b1a59f9 | ||
![]() |
5299c5c4be | ||
![]() |
f7756bccef | ||
![]() |
a6b874d160 | ||
![]() |
3e5fb3ddcf | ||
![]() |
5e6bcb12d3 | ||
![]() |
14303f1429 | ||
![]() |
96711ba022 | ||
![]() |
cbfc0fdbdc | ||
![]() |
6e81886c0e | ||
![]() |
2d976bc132 | ||
![]() |
57f6a476af | ||
![]() |
8491ed296e | ||
![]() |
cd1288afdc | ||
![]() |
ec6c830cb0 | ||
![]() |
2f86ccc4bf | ||
![]() |
8ca445aec0 | ||
![]() |
1e1f27c8a5 | ||
![]() |
2b84bde367 | ||
![]() |
b52e58551d | ||
![]() |
9aceed00bf | ||
![]() |
58814f7f74 | ||
![]() |
6a70ef9f31 | ||
![]() |
82cc4ca500 | ||
![]() |
4567fa04ed | ||
![]() |
8b98b5d818 | ||
![]() |
176d0351af | ||
![]() |
d63dc3384b | ||
![]() |
1ccd704e30 | ||
![]() |
f5d23dbe79 | ||
![]() |
75bfe53ac3 | ||
![]() |
3308f916dd | ||
![]() |
e7140279ca | ||
![]() |
1034719f5e | ||
![]() |
2c00043a7f | ||
![]() |
65c695d9ce | ||
![]() |
57253fe46a | ||
![]() |
4e5c443440 | ||
![]() |
0b3b73d8ec | ||
![]() |
921eabc134 | ||
![]() |
0faa428751 | ||
![]() |
f71a2fdd63 | ||
![]() |
4eb9ed8aba | ||
![]() |
d7b549abb8 | ||
![]() |
95d723c578 | ||
![]() |
2fcd853e86 | ||
![]() |
07eef7c812 | ||
![]() |
b01e0757fa | ||
![]() |
32844a20c6 | ||
![]() |
5b6532c601 | ||
![]() |
2c5b4b4027 | ||
![]() |
72d7ecf195 | ||
![]() |
2cfa6b4306 | ||
![]() |
6f6ffde0ab | ||
![]() |
1694739a16 | ||
![]() |
95d1e8bfca | ||
![]() |
60dec08e3c | ||
![]() |
a99d71be93 | ||
![]() |
f1331b6a0c | ||
![]() |
10d66b642b | ||
![]() |
cd2310e4a8 | ||
![]() |
1b399cf6b0 |
@@ -22,7 +22,9 @@
|
||||
|
||||
[ThingsGateway演示地址](http://120.24.62.140:5000/)
|
||||
|
||||
账户 : **superAdmin** 密码 : **111111**
|
||||
账户 : **superAdmin**
|
||||
|
||||
密码 : **111111**
|
||||
|
||||
## 赞助
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Version>2.0.7.0</Version>
|
||||
<Version>2.1.0.9</Version>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
|
@@ -51,7 +51,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadOperateLogAsync([FromQuery] OperateLogInput input)
|
||||
{
|
||||
var memoryStream = await _operateLogService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"operateLog{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
@@ -66,7 +65,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadVisitLogAsync([FromQuery] VisitLogInput input)
|
||||
{
|
||||
var memoryStream = await _visitLogService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"operateLog{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
|
@@ -18,6 +18,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
using UAParser;
|
||||
|
||||
|
@@ -20,6 +20,7 @@ using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
|
@@ -13,6 +13,8 @@
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
/// <summary>
|
||||
|
@@ -88,8 +88,7 @@ public class AuthService : IAuthService
|
||||
}
|
||||
|
||||
var password = DESCEncryption.Decrypt(input.Password, DESCKeyConst.DESCKey); // 解密
|
||||
var userInfo = await _userService.GetUserByAccountAsync(input.Account);//获取用户信息
|
||||
if (userInfo == null) throw Oops.Bah("用户不存在");//用户不存在
|
||||
var userInfo = await _userService.GetUserByAccountAsync(input.Account) ?? throw Oops.Bah("用户不存在");//获取用户信息
|
||||
if (userInfo.Password != password) throw Oops.Bah("账号密码错误");//账号密码错误
|
||||
return await LoginAsync(userInfo, input.Device);
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ using Furion.FriendlyException;
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
|
@@ -66,6 +66,7 @@ public class OperateLogService : DbRepository<SysOperateLog>, IOperateLogService
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,7 @@ using Furion.FriendlyException;
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
|
@@ -19,6 +19,7 @@ using Mapster;
|
||||
using SqlSugar;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
|
@@ -17,6 +17,7 @@ using Furion.FriendlyException;
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
|
@@ -92,6 +92,7 @@ public class VisitLogService : DbRepository<SysVisitLog>, IVisitLogService
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
|
@@ -30,7 +30,9 @@ public class BaseComponentBase : ComponentBase, IDisposable
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// InvokeAsync(StateHasChanged)
|
||||
/// </summary>
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -20,19 +20,19 @@ namespace ThingsGateway.Admin.Blazor.Core;
|
||||
public partial class AppBarItems
|
||||
{
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 链接
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_COPYRIGHT_URL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>Ȩ
|
||||
/// 版权
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_COPYRIGHT { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 标题
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_TITLE { get; set; }
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor.Core;
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>/ͣ<><CDA3> <20>ı<EFBFBD><C4B1><EFBFBD>ʾ
|
||||
/// 启用/停用 文本提示
|
||||
/// </summary>
|
||||
public partial class EnableChip
|
||||
{
|
||||
@@ -46,5 +46,5 @@ public partial class EnableChip
|
||||
|
||||
private string TextColor => Value ? "green" : "error";
|
||||
private string Color => Value ? "green-lighten" : "warning-lighten";
|
||||
private string Label => Value ? EnabledLabel ?? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : DisabledLabel ?? "ͣ<EFBFBD><EFBFBD>";
|
||||
private string Label => Value ? EnabledLabel ?? "启用" : DisabledLabel ?? "停用";
|
||||
}
|
@@ -1,18 +1,18 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor.Core;
|
||||
/// <summary>
|
||||
/// <EFBFBD>ղ<EFBFBD>/<2F><><EFBFBD>ݷ<EFBFBD>ʽ
|
||||
/// 收藏/快捷方式
|
||||
/// </summary>
|
||||
public partial class Favorite
|
||||
{
|
||||
|
@@ -19,7 +19,7 @@
|
||||
<MSheet>
|
||||
<MCard Flat Href=@CONFIG_COPYRIGHT_URL Target="_blank">
|
||||
<MLabel Style="background-color:inherit;" Class="text-subtltie-2">@CONFIG_COPYRIGHT</MLabel>
|
||||
<MLabel Style="background-color:inherit;" Class="text-subtltie-2 ml-4">@Version</MLabel>
|
||||
<MLabel Style="background-color:inherit;white-space: pre;" Class="text-subtltie-2 ml-4">@Version</MLabel>
|
||||
</MCard>
|
||||
</MSheet>
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -14,6 +14,8 @@ using Microsoft.AspNetCore.Components;
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor.Core;
|
||||
/// <summary>
|
||||
/// Foter
|
||||
@@ -22,17 +24,17 @@ public partial class Foter
|
||||
{
|
||||
private string Version = "";
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 链接
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_COPYRIGHT_URL { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>Ȩ
|
||||
/// 版权
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_COPYRIGHT { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 标题
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_TITLE { get; set; }
|
||||
@@ -40,7 +42,12 @@ public partial class Foter
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Version = "v" + Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
var assembly = Assembly.GetEntryAssembly();
|
||||
if (assembly != null)
|
||||
{
|
||||
Version = $"v{assembly.GetName().Version}";
|
||||
}
|
||||
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -20,23 +20,23 @@ namespace ThingsGateway.Admin.Blazor.Core;
|
||||
public partial class Logo
|
||||
{
|
||||
/// <summary>
|
||||
/// Logo<EFBFBD>߶<EFBFBD>
|
||||
/// Logo高度
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int HeightInt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 链接
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_COPYRIGHT_URL { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>Ȩ
|
||||
/// 版权
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_COPYRIGHT { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 标题
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string CONFIG_TITLE { get; set; }
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -34,7 +34,7 @@ public partial class PageTabs
|
||||
return op;
|
||||
}
|
||||
/// <summary>
|
||||
/// Tabsʵ<EFBFBD><EFBFBD>
|
||||
/// Tabs实例
|
||||
/// </summary>
|
||||
public PPageTabs PPageTabs { get; private set; }
|
||||
|
||||
@@ -46,7 +46,7 @@ public partial class PageTabs
|
||||
[Parameter]
|
||||
public IEnumerable<string> SelfPatterns { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 子组件
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -17,6 +17,7 @@ using Masa.Blazor;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor.Core;
|
||||
/// <summary>
|
||||
@@ -49,11 +50,11 @@ public partial class UserMenu
|
||||
var ret = str?.ToJsonWithT<UnifyResult<string>>();
|
||||
if (ret?.Code != 200)
|
||||
{
|
||||
await PopupService.EnqueueSnackbarAsync("ע<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>", AlertTypes.Error);
|
||||
await PopupService.EnqueueSnackbarAsync("注销失败", AlertTypes.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
await PopupService.EnqueueSnackbarAsync("ע<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
|
||||
await PopupService.EnqueueSnackbarAsync("注销成功", AlertTypes.Success);
|
||||
await Task.Delay(500);
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri);
|
||||
}
|
||||
|
@@ -0,0 +1,68 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion.DependencyInjection;
|
||||
|
||||
namespace BlazorComponent.I18n;
|
||||
/// <summary>
|
||||
/// CookieStorage
|
||||
/// </summary>
|
||||
public class CookieStorage : IScoped
|
||||
{
|
||||
private readonly IJSRuntime _jsRuntime;
|
||||
/// <summary>
|
||||
/// CookieStorage
|
||||
/// </summary>
|
||||
/// <param name="jsRuntime"></param>
|
||||
public CookieStorage(IJSRuntime jsRuntime)
|
||||
{
|
||||
_jsRuntime = jsRuntime;
|
||||
}
|
||||
/// <summary>
|
||||
/// GetCookieAsync
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GetCookieAsync(string key)
|
||||
{
|
||||
return await _jsRuntime.InvokeAsync<string>(JsInteropConstants.GetCookie, key);
|
||||
}
|
||||
/// <summary>
|
||||
/// GetCookie
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public string GetCookie(string key)
|
||||
{
|
||||
if (_jsRuntime is IJSInProcessRuntime jsInProcess)
|
||||
{
|
||||
return jsInProcess.Invoke<string>(JsInteropConstants.GetCookie, key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// SetItemAsync
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public async void SetItemAsync<T>(string key, T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _jsRuntime.InvokeVoidAsync(JsInteropConstants.SetCookie, key, value?.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using BlazorComponent;
|
||||
|
||||
using Furion;
|
||||
|
||||
using Masa.Blazor;
|
||||
@@ -61,6 +63,8 @@ public class Startup : AppStartup
|
||||
|
||||
|
||||
});
|
||||
options.Locale = new Locale("zh-CN", "en-US");
|
||||
|
||||
});
|
||||
|
||||
services.AddScoped<InitTimezone>();
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="Masa.Blazor" Version="1.0.1" />
|
||||
<PackageReference Include="Masa.Blazor" Version="1.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.10" />
|
||||
|
||||
</ItemGroup>
|
||||
|
@@ -857,5 +857,38 @@
|
||||
设置深浅主题统一由这个方法为入口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:BlazorComponent.I18n.CookieStorage">
|
||||
<summary>
|
||||
CookieStorage
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:BlazorComponent.I18n.CookieStorage.#ctor(Microsoft.JSInterop.IJSRuntime)">
|
||||
<summary>
|
||||
CookieStorage
|
||||
</summary>
|
||||
<param name="jsRuntime"></param>
|
||||
</member>
|
||||
<member name="M:BlazorComponent.I18n.CookieStorage.GetCookieAsync(System.String)">
|
||||
<summary>
|
||||
GetCookieAsync
|
||||
</summary>
|
||||
<param name="key"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:BlazorComponent.I18n.CookieStorage.GetCookie(System.String)">
|
||||
<summary>
|
||||
GetCookie
|
||||
</summary>
|
||||
<param name="key"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:BlazorComponent.I18n.CookieStorage.SetItemAsync``1(System.String,``0)">
|
||||
<summary>
|
||||
SetItemAsync
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="key"></param>
|
||||
<param name="value"></param>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
@@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Http;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor.Core;
|
||||
|
||||
@@ -153,7 +154,7 @@ public class UserResoures : IDisposable
|
||||
{
|
||||
if (MasaBlazor.Theme.Dark != isDark || isDark == null)
|
||||
MasaBlazor.ToggleTheme();
|
||||
_cookieStorage?.SetItemAsync(BlazorResourceConst.ThemeCookieKey, isDark.ToJsonString());
|
||||
_cookieStorage?.SetItemAsync(BlazorResourceConst.ThemeCookieKey, MasaBlazor.Theme.Dark.ToJsonString());
|
||||
}
|
||||
|
||||
private void InitCookie(IRequestCookieCollection cookies)
|
||||
|
@@ -282,6 +282,7 @@ public partial class AppDataTable<TItem, SearchItem, AddItem, EditItem> : IAppDa
|
||||
{
|
||||
SearchModel.Size = PageItems.Total;
|
||||
}
|
||||
selectedItem = new List<TItem>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
@@ -14,8 +14,7 @@
|
||||
@using System.Linq.Expressions;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
|
||||
@inject IConfigService ConfigService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inject UserResoures UserResoures
|
||||
|
@@ -41,26 +41,26 @@ public partial class Config
|
||||
MainLayout MainLayout { get; set; }
|
||||
private Task AddCallAsync(ConfigAddInput input)
|
||||
{
|
||||
return ConfigService.AddAsync(input);
|
||||
return App.GetService<ConfigService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private Task DeleteCallAsync(IEnumerable<SysConfig> sysConfigs)
|
||||
{
|
||||
return ConfigService.DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
|
||||
return App.GetService<ConfigService>().DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
|
||||
}
|
||||
private Task EditCallAsync(ConfigEditInput sysConfigs)
|
||||
{
|
||||
return ConfigService.EditAsync(sysConfigs);
|
||||
return App.GetService<ConfigService>().EditAsync(sysConfigs);
|
||||
}
|
||||
|
||||
private async Task OnSaveAsync()
|
||||
{
|
||||
await ConfigService.EditBatchAsync(_sysConfig);
|
||||
await App.GetService<ConfigService>().EditBatchAsync(_sysConfig);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
private Task<SqlSugarPagedList<SysConfig>> QueryCallAsync(ConfigPageInput input)
|
||||
{
|
||||
return ConfigService.PageAsync(input);
|
||||
return App.GetService<ConfigService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -18,7 +18,7 @@ using ThingsGateway.Admin.Core;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor;
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ҳ
|
||||
/// 首页
|
||||
/// </summary>
|
||||
public partial class Index
|
||||
{
|
||||
|
@@ -16,7 +16,7 @@
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
@inject IMenuService MenuService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inherits BaseComponentBase
|
||||
|
@@ -29,14 +29,11 @@ public partial class Menu
|
||||
long buttonParentId;
|
||||
bool IsShowButtonList;
|
||||
List<SysResource> MenuCatalog = new();
|
||||
[Inject]
|
||||
IButtonService ButtonService { get; set; }
|
||||
|
||||
|
||||
[CascadingParameter]
|
||||
MainLayout MainLayout { get; set; }
|
||||
|
||||
[Inject]
|
||||
IResourceService ResourceService { get; set; }
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
@@ -52,23 +49,23 @@ public partial class Menu
|
||||
private async Task AddCallAsync(MenuAddInput input)
|
||||
{
|
||||
input.ParentId = search.ParentId;
|
||||
await MenuService.AddAsync(input);
|
||||
await App.GetService<MenuService>().AddAsync(input);
|
||||
await NavChangeAsync();
|
||||
}
|
||||
private async Task ButtonAddCallAsync(ButtonAddInput input)
|
||||
{
|
||||
input.ParentId = buttonParentId;
|
||||
await ButtonService.AddAsync(input);
|
||||
await App.GetService<ButtonService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private Task ButtonDeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
return ButtonService.DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
return App.GetService<ButtonService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
}
|
||||
|
||||
private Task ButtonEditCallAsync(ButtonEditInput input)
|
||||
{
|
||||
return ButtonService.EditAsync(input);
|
||||
return App.GetService<ButtonService>().EditAsync(input);
|
||||
|
||||
}
|
||||
|
||||
@@ -92,7 +89,7 @@ public partial class Menu
|
||||
private async Task<SqlSugarPagedList<SysResource>> ButtonQueryCallAsync(ButtonPageInput input)
|
||||
{
|
||||
input.ParentId = buttonParentId;
|
||||
var data = await ButtonService.PageAsync(input);
|
||||
var data = await App.GetService<ButtonService>().PageAsync(input);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -103,13 +100,13 @@ public partial class Menu
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await MenuService.DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await App.GetService<MenuService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await NavChangeAsync();
|
||||
|
||||
}
|
||||
private async Task EditCallAsync(MenuEditInput input)
|
||||
{
|
||||
await MenuService.EditAsync(input);
|
||||
await App.GetService<MenuService>().EditAsync(input);
|
||||
await NavChangeAsync();
|
||||
|
||||
}
|
||||
@@ -117,9 +114,9 @@ public partial class Menu
|
||||
private async Task<List<SysResource>> GetMenuCatalogAsync()
|
||||
{
|
||||
//获取所有菜单
|
||||
List<SysResource> sysResources = await ResourceService.GetListByCategoryAsync(ResourceCategoryEnum.MENU);
|
||||
List<SysResource> sysResources = await App.GetService<ResourceService>().GetListByCategoryAsync(ResourceCategoryEnum.MENU);
|
||||
sysResources = sysResources.Where(it => it.TargetType == TargetTypeEnum.None).ToList();
|
||||
MenuCatalog = ResourceService.ResourceListToTree(sysResources);
|
||||
MenuCatalog = App.GetService<ResourceService>().ResourceListToTree(sysResources);
|
||||
return MenuCatalog;
|
||||
}
|
||||
|
||||
@@ -130,7 +127,7 @@ public partial class Menu
|
||||
}
|
||||
private async Task<SqlSugarPagedList<SysResource>> QueryCallAsync(MenuPageInput input)
|
||||
{
|
||||
var data = await MenuService.TreeAsync(input);
|
||||
var data = await App.GetService<MenuService>().TreeAsync(input);
|
||||
return data.ToPagedList(input);
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
@inject IOpenApiSessionService SessionService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inject UserResoures UserResoures
|
||||
|
@@ -33,13 +33,13 @@ public partial class OpenApiSession
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await SessionService.ExitSessionAsync(id);
|
||||
await App.GetService<OpenApiSessionService>().ExitSessionAsync(id);
|
||||
}
|
||||
}
|
||||
|
||||
private Task<SqlSugarPagedList<OpenApiSessionOutput>> SessionQueryCallAsync(OpenApiSessionPageInput input)
|
||||
{
|
||||
return SessionService.PageAsync(input);
|
||||
return App.GetService<OpenApiSessionService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
|
||||
@@ -57,7 +57,7 @@ public partial class OpenApiSession
|
||||
VerificatIds = verificats.Select(it => it.Id).ToList(),
|
||||
Id = verificats.First().UserId
|
||||
};
|
||||
await SessionService.ExitVerificatAsync(send);
|
||||
await App.GetService<OpenApiSessionService>().ExitVerificatAsync(send);
|
||||
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
@using Masa.Blazor.Presets;
|
||||
@inject IOpenApiUserService OpenApiUserService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inject UserResoures UserResoures
|
||||
|
@@ -31,21 +31,20 @@ public partial class OpenApiUserR
|
||||
bool IsShowRoles;
|
||||
List<OpenApiPermissionTreeSelector> RolesChoice = new();
|
||||
string SearchName;
|
||||
[Inject]
|
||||
IRoleService SysRoleService { get; set; }
|
||||
|
||||
private Task AddCallAsync(OpenApiUserAddInput input)
|
||||
{
|
||||
return OpenApiUserService.AddAsync(input);
|
||||
return App.GetService<OpenApiUserService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<OpenApiUser> users)
|
||||
{
|
||||
await OpenApiUserService.DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await App.GetService<OpenApiUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
}
|
||||
|
||||
private Task EditCallAsync(OpenApiUserEditInput users)
|
||||
{
|
||||
return OpenApiUserService.EditAsync(users);
|
||||
return App.GetService<OpenApiUserService>().EditAsync(users);
|
||||
}
|
||||
|
||||
private List<OpenApiPermissionTreeSelector> GetRouters()
|
||||
@@ -61,7 +60,7 @@ public partial class OpenApiUserR
|
||||
OpenApiUserGrantPermissionInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = ChoiceUserId;
|
||||
userGrantRoleInput.PermissionList = RolesChoice.Select(it => it.ApiRoute).ToList();
|
||||
await OpenApiUserService.GrantRoleAsync(userGrantRoleInput);
|
||||
await App.GetService<OpenApiUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
IsShowRoles = false;
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
@@ -73,7 +72,7 @@ public partial class OpenApiUserR
|
||||
}
|
||||
private Task<SqlSugarPagedList<OpenApiUser>> QueryCallAsync(OpenApiUserPageInput input)
|
||||
{
|
||||
return OpenApiUserService.PageAsync(input);
|
||||
return App.GetService<OpenApiUserService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task UserStatusChangeAsync(OpenApiUser context, bool enable)
|
||||
@@ -81,9 +80,9 @@ public partial class OpenApiUserR
|
||||
try
|
||||
{
|
||||
if (enable)
|
||||
await OpenApiUserService.EnableUserAsync(context.Id);
|
||||
await App.GetService<OpenApiUserService>().EnableUserAsync(context.Id);
|
||||
else
|
||||
await OpenApiUserService.DisableUserAsync(context.Id);
|
||||
await App.GetService<OpenApiUserService>().DisableUserAsync(context.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -14,7 +14,7 @@
|
||||
@using System.Linq.Expressions;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
@inject IOperateLogService OperateLogService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inject UserResoures UserResoures
|
||||
|
@@ -44,7 +44,7 @@ public partial class Oplog
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await OperateLogService.DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
|
||||
await App.GetService<OperateLogService>().DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public partial class Oplog
|
||||
input.Account = search.Account;
|
||||
input.Category = search.Category;
|
||||
input.ExeStatus = search.ExeStatus;
|
||||
return OperateLogService.PageAsync(input);
|
||||
return App.GetService<OperateLogService>().PageAsync(input);
|
||||
}
|
||||
[Inject]
|
||||
AjaxService AjaxService { get; set; }
|
||||
|
@@ -16,7 +16,7 @@
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
@inject IRoleService SysRoleService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inject UserResoures UserResoures
|
||||
|
@@ -38,27 +38,23 @@ public partial class Role
|
||||
[CascadingParameter]
|
||||
MainLayout MainLayout { get; set; }
|
||||
|
||||
[Inject]
|
||||
IResourceService ResourceService { get; set; }
|
||||
|
||||
|
||||
private string SearchKey { get; set; }
|
||||
|
||||
[Inject]
|
||||
ISysUserService SysUserService { get; set; }
|
||||
|
||||
private Task AddCallAsync(RoleAddInput input)
|
||||
{
|
||||
return SysRoleService.AddAsync(input);
|
||||
return App.GetService<RoleService>().AddAsync(input);
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysRole> sysRoles)
|
||||
{
|
||||
await SysRoleService.DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
|
||||
await App.GetService<RoleService>().DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(RoleEditInput input)
|
||||
{
|
||||
await SysRoleService.EditAsync(input);
|
||||
await App.GetService<RoleService>().EditAsync(input);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
private async Task OnRoleHasResuorcesSaveAsync(ModalActionEventArgs args)
|
||||
@@ -69,7 +65,7 @@ public partial class Role
|
||||
var data = new List<SysResource>();
|
||||
userGrantRoleInput.Id = ChoiceRoleId;
|
||||
userGrantRoleInput.GrantInfoList = RoleHasResuorces;
|
||||
await SysRoleService.GrantResourceAsync(userGrantRoleInput);
|
||||
await App.GetService<RoleService>().GrantResourceAsync(userGrantRoleInput);
|
||||
IsShowResuorces = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -86,7 +82,7 @@ public partial class Role
|
||||
GrantUserInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = ChoiceRoleId;
|
||||
userGrantRoleInput.GrantInfoList = UsersChoice.Select(it => it.Id).ToList();
|
||||
await SysRoleService.GrantUserAsync(userGrantRoleInput);
|
||||
await App.GetService<RoleService>().GrantUserAsync(userGrantRoleInput);
|
||||
IsShowUsers = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -99,19 +95,19 @@ public partial class Role
|
||||
|
||||
private Task<SqlSugarPagedList<SysRole>> QueryCallAsync(RolePageInput input)
|
||||
{
|
||||
return SysRoleService.PageAsync(input);
|
||||
return App.GetService<RoleService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ResuorceInitAsync()
|
||||
{
|
||||
ResTreeSelectors = (await ResourceService.GetRoleGrantResourceMenusAsync());
|
||||
RoleHasResuorces = (await SysRoleService.OwnResourceAsync(ChoiceRoleId))?.GrantInfoList;
|
||||
ResTreeSelectors = (await App.GetService<ResourceService>().GetRoleGrantResourceMenusAsync());
|
||||
RoleHasResuorces = (await App.GetService<RoleService>().OwnResourceAsync(ChoiceRoleId))?.GrantInfoList;
|
||||
}
|
||||
|
||||
private async Task<List<UserSelectorOutput>> UserInitAsync()
|
||||
{
|
||||
AllUsers = await SysUserService.UserSelectorAsync(SearchKey);
|
||||
var data = await SysRoleService.OwnUserAsync(ChoiceRoleId);
|
||||
AllUsers = await App.GetService<SysUserService>().UserSelectorAsync(SearchKey);
|
||||
var data = await App.GetService<RoleService>().OwnUserAsync(ChoiceRoleId);
|
||||
UsersChoice = AllUsers.Where(a => data.Contains(a.Id)).ToList();
|
||||
return AllUsers;
|
||||
}
|
||||
|
@@ -15,8 +15,7 @@
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
|
||||
@inject ISessionService SessionService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inject UserResoures UserResoures
|
||||
|
@@ -33,14 +33,14 @@ public partial class Session
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await SessionService.ExitSessionAsync(id);
|
||||
await App.GetService<SessionService>().ExitSessionAsync(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Task<SqlSugarPagedList<SessionOutput>> SessionQueryCallAsync(SessionPageInput input)
|
||||
{
|
||||
return SessionService.PageAsync(input);
|
||||
return App.GetService<SessionService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
|
||||
@@ -58,7 +58,7 @@ public partial class Session
|
||||
VerificatIds = verificats.Select(it => it.Id).ToList(),
|
||||
Id = verificats.First().UserId
|
||||
};
|
||||
await SessionService.ExitVerificatAsync(send);
|
||||
await App.GetService<SessionService>().ExitVerificatAsync(send);
|
||||
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
@inject ISpaService SpaService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inherits BaseComponentBase
|
||||
|
@@ -27,23 +27,23 @@ public partial class Spa
|
||||
|
||||
private async Task AddCallAsync(SpaAddInput input)
|
||||
{
|
||||
await SpaService.AddAsync(input);
|
||||
await App.GetService<SpaService>().AddAsync(input);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await SpaService.DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await App.GetService<SpaService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(SpaEditInput input)
|
||||
{
|
||||
await SpaService.EditAsync(input);
|
||||
await App.GetService<SpaService>().EditAsync(input);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private Task<SqlSugarPagedList<SysResource>> QueryCallAsync(SpaPageInput input)
|
||||
{
|
||||
return SpaService.PageAsync(input);
|
||||
return App.GetService<SpaService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -11,7 +11,7 @@
|
||||
*@
|
||||
|
||||
@page "/admin/user"
|
||||
@inject ISysUserService SysUserService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@using Masa.Blazor.Presets;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
|
@@ -34,21 +34,20 @@ public partial class User
|
||||
[CascadingParameter]
|
||||
MainLayout MainLayout { get; set; }
|
||||
|
||||
[Inject]
|
||||
IRoleService SysRoleService { get; set; }
|
||||
|
||||
private Task AddCallAsync(UserAddInput input)
|
||||
{
|
||||
return SysUserService.AddAsync(input);
|
||||
return App.GetService<SysUserService>().AddAsync(input);
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysUser> users)
|
||||
{
|
||||
await SysUserService.DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await App.GetService<SysUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(UserEditInput users)
|
||||
{
|
||||
await SysUserService.EditAsync(users);
|
||||
await App.GetService<SysUserService>().EditAsync(users);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
@@ -59,7 +58,7 @@ public partial class User
|
||||
UserGrantRoleInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = ChoiceUserId;
|
||||
userGrantRoleInput.RoleIdList = RolesChoice.Select(it => it.Id).ToList();
|
||||
await SysUserService.GrantRoleAsync(userGrantRoleInput);
|
||||
await App.GetService<SysUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
IsShowRoles = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -71,20 +70,20 @@ public partial class User
|
||||
}
|
||||
private Task<SqlSugarPagedList<SysUser>> QueryCallAsync(UserPageInput input)
|
||||
{
|
||||
return SysUserService.PageAsync(input);
|
||||
return App.GetService<SysUserService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ResetPasswordAsync(SysUser sysUser)
|
||||
{
|
||||
await SysUserService.ResetPasswordAsync(sysUser.Id);
|
||||
await App.GetService<SysUserService>().ResetPasswordAsync(sysUser.Id);
|
||||
await PopupService.EnqueueSnackbarAsync(new("成功", AlertTypes.Success));
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task RoleInitAsync()
|
||||
{
|
||||
AllRoles = await SysRoleService.RoleSelectorAsync();
|
||||
var data = await SysRoleService.GetRoleIdListByUserIdAsync(ChoiceUserId);
|
||||
AllRoles = await App.GetService<RoleService>().RoleSelectorAsync();
|
||||
var data = await App.GetService<RoleService>().GetRoleIdListByUserIdAsync(ChoiceUserId);
|
||||
RolesChoice = AllRoles.Where(a => data.Contains(a.Id)).ToList();
|
||||
}
|
||||
private async Task UserStatusChangeAsync(SysUser context, bool enable)
|
||||
@@ -92,9 +91,9 @@ public partial class User
|
||||
try
|
||||
{
|
||||
if (enable)
|
||||
await SysUserService.EnableUserAsync(context.Id);
|
||||
await App.GetService<SysUserService>().EnableUserAsync(context.Id);
|
||||
else
|
||||
await SysUserService.DisableUserAsync(context.Id);
|
||||
await App.GetService<SysUserService>().DisableUserAsync(context.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -18,7 +18,7 @@ using ThingsGateway.Admin.Core;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor;
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 个人设置
|
||||
/// </summary>
|
||||
public partial class UserCenter
|
||||
{
|
||||
@@ -33,8 +33,7 @@ public partial class UserCenter
|
||||
[Inject]
|
||||
NavigationManager NavigationManager { get; set; }
|
||||
|
||||
[Inject]
|
||||
IUserCenterService UserCenterService { get; set; }
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnParametersSetAsync()
|
||||
@@ -48,27 +47,27 @@ public partial class UserCenter
|
||||
|
||||
async Task OnDefaultRazorSaveAsync()
|
||||
{
|
||||
await UserCenterService.UpdateUserDefaultRazorAsync(UserManager.UserId, DefaultMenuId);
|
||||
await App.GetService<UserCenterService>().UpdateUserDefaultRazorAsync(UserManager.UserId, DefaultMenuId);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
|
||||
async Task OnShortcutSaveAsync()
|
||||
{
|
||||
await UserCenterService.UpdateWorkbenchAsync(_menusChoice);
|
||||
await App.GetService<UserCenterService>().UpdateWorkbenchAsync(_menusChoice);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
async Task OnUpdatePasswordInfoAsync(FormContext context)
|
||||
{
|
||||
var success = context.Validate();
|
||||
if (success)
|
||||
{
|
||||
//<EFBFBD><EFBFBD>֤<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD>
|
||||
//验证成功,操作业务
|
||||
_passwordInfoInput.Id = UserResoures.CurrentUser.Id;
|
||||
await UserCenterService.EditPasswordAsync(_passwordInfoInput);
|
||||
await App.GetService<UserCenterService>().EditPasswordAsync(_passwordInfoInput);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>¼", AlertTypes.Success);
|
||||
await PopupService.EnqueueSnackbarAsync("成功,将重新登录", AlertTypes.Success);
|
||||
await Task.Delay(2000);
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri);
|
||||
}
|
||||
@@ -76,8 +75,8 @@ public partial class UserCenter
|
||||
|
||||
async Task OnUpdateUserInfoAsync()
|
||||
{
|
||||
await UserCenterService.UpdateUserInfoAsync(_updateInfoInput);
|
||||
await App.GetService<UserCenterService>().UpdateUserInfoAsync(_updateInfoInput);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
}
|
@@ -14,8 +14,7 @@
|
||||
@using System.Linq.Expressions;
|
||||
@using Microsoft.AspNetCore.Authorization;
|
||||
@using ThingsGateway.Admin.Application;
|
||||
|
||||
@inject IVisitLogService VisitLogService
|
||||
|
||||
@namespace ThingsGateway.Admin.Blazor
|
||||
@attribute [Authorize]
|
||||
@inject UserResoures UserResoures
|
||||
|
@@ -51,14 +51,14 @@ public partial class Vislog
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await VisitLogService.DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
|
||||
await App.GetService<VisitLogService>().DeleteAsync(CategoryFilters.Select(it => it.Value).ToArray());
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<SqlSugarPagedList<SysVisitLog>> QueryCallAsync(VisitLogPageInput input)
|
||||
{
|
||||
var data = await VisitLogService.PageAsync(input);
|
||||
var data = await App.GetService<VisitLogService>().PageAsync(input);
|
||||
return data;
|
||||
}
|
||||
[Inject]
|
||||
|
@@ -21,6 +21,7 @@ using Microsoft.Extensions.Hosting;
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Admin.Blazor.Core;
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor;
|
||||
|
||||
@@ -39,10 +40,6 @@ public partial class Login
|
||||
AjaxService AjaxService { get; set; }
|
||||
|
||||
|
||||
[Inject]
|
||||
IAuthService AuthService { get; set; }
|
||||
|
||||
|
||||
|
||||
string UserLogoUrl { get; set; } = BlazorResourceConst.ResourceUrl + "images/defaultUser.svg";
|
||||
|
||||
@@ -64,12 +61,7 @@ public partial class Login
|
||||
}
|
||||
}
|
||||
private PImageCaptcha captcha;
|
||||
[Inject]
|
||||
IUserCenterService UserCenterService { get; set; }
|
||||
[Inject]
|
||||
IResourceService ResourceService { get; set; }
|
||||
[Inject]
|
||||
ISysUserService SysUserService { get; set; }
|
||||
|
||||
private async Task LoginAsync()
|
||||
{
|
||||
loginModel.ValidCodeReqNo = CaptchaInfo.ValidCodeReqNo;
|
||||
@@ -101,9 +93,9 @@ public partial class Login
|
||||
{
|
||||
await PopupService.EnqueueSnackbarAsync(new("登录成功", AlertTypes.Success));
|
||||
await Task.Delay(500);
|
||||
var userId = await SysUserService.GetIdByAccountAsync(loginModel.Account);
|
||||
var data = await UserCenterService.GetLoginDefaultRazorAsync(userId);
|
||||
var sameLevelMenus = await ResourceService.GetaMenuAndSpaListAsync();
|
||||
var userId = await App.GetService<SysUserService>().GetIdByAccountAsync(loginModel.Account);
|
||||
var data = await App.GetService<UserCenterService>().GetLoginDefaultRazorAsync(userId);
|
||||
var sameLevelMenus = await App.GetService<ResourceService>().GetaMenuAndSpaListAsync();
|
||||
if (NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/Login" || NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/")
|
||||
await AjaxService.GotoAsync(sameLevelMenus.FirstOrDefault(a => a.Id == data)?.Component ?? "index");
|
||||
else
|
||||
@@ -140,12 +132,12 @@ public partial class Login
|
||||
|
||||
private void GetCaptchaInfo()
|
||||
{
|
||||
CaptchaInfo = AuthService.GetCaptchaInfo();
|
||||
CaptchaInfo = App.GetService<AuthService>().GetCaptchaInfo();
|
||||
}
|
||||
|
||||
private Task<string> RefreshCode()
|
||||
{
|
||||
CaptchaInfo = AuthService.GetCaptchaInfo();
|
||||
CaptchaInfo = App.GetService<AuthService>().GetCaptchaInfo();
|
||||
return Task.FromResult(CaptchaInfo.CodeValue);
|
||||
}
|
||||
}
|
@@ -86,7 +86,7 @@ public class OpenApiUser : BaseEntity
|
||||
/// <summary>
|
||||
/// 权限码集合
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "PermissionCodeList", ColumnDescription = "权限json", IsJson = true, IsNullable = true)]
|
||||
[SugarColumn(ColumnName = "PermissionCodeList", ColumnDescription = "权限json", ColumnDataType = StaticConfig.CodeFirst_BigString, IsJson = true, IsNullable = true)]
|
||||
public List<string> PermissionCodeList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
@@ -31,7 +31,7 @@ public class SysVerificat : PrimaryIdEntity
|
||||
/// <summary>
|
||||
/// 会话信息列表
|
||||
/// </summary>
|
||||
[SugarColumn(IsJson = true)]
|
||||
[SugarColumn(ColumnName = "VerificatInfos", ColumnDescription = "会话信息列表", ColumnDataType = StaticConfig.CodeFirst_BigString, IsJson = true, IsNullable = true)]
|
||||
public List<VerificatInfo> VerificatInfos { get; set; }
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
using Furion.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
namespace ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
/// <summary>
|
||||
/// 对象拓展
|
||||
|
@@ -18,6 +18,8 @@ using System.Collections;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
|
@@ -332,20 +332,51 @@ public static class ObjectExtensions
|
||||
/// <returns></returns>
|
||||
public static bool ToBoolean(this object value, bool defaultValue = false) => value?.ToString().ToUpper() switch
|
||||
{
|
||||
"0" or "FALSE" => false,
|
||||
"1" or "TRUE" => true,
|
||||
_ => defaultValue,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// ToLong
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static long ToLong(this object value, long defaultValue = 0) => value == null || value.ToString().IsNullOrEmpty() ? defaultValue : Int64.TryParse(value.ToString(), out var n) ? n : defaultValue;
|
||||
public static long ToLong(this object value, long defaultValue = 0)
|
||||
{
|
||||
if (value == null || value.ToString().IsNullOrEmpty())
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return Int64.TryParse(value.ToString(), out var n) ? n : defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ToInt
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int ToInt(this object value, int defaultValue = 0) => value == null || value.ToString().IsNullOrEmpty() ? defaultValue : Int32.TryParse(value.ToString(), out var n) ? n : defaultValue;
|
||||
public static int ToInt(this object value, int defaultValue = 0)
|
||||
{
|
||||
if (value == null || value.ToString().IsNullOrEmpty())
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return int.TryParse(value.ToString(), out int n) ? n : defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ToDecimal
|
||||
/// </summary>
|
||||
@@ -357,7 +388,18 @@ public static class ObjectExtensions
|
||||
return Double.IsNaN(d) ? defaultValue : (Decimal)d;
|
||||
}
|
||||
var str = value?.ToString();
|
||||
return str.IsNullOrEmpty() ? defaultValue : Decimal.TryParse(str, out var n) ? n : defaultValue;
|
||||
if (str.IsNullOrEmpty())
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return Decimal.TryParse(str, out var n) ? n : defaultValue;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// ToDecimal
|
||||
@@ -370,7 +412,18 @@ public static class ObjectExtensions
|
||||
return Double.IsNaN(d) ? defaultValue : (Double)d;
|
||||
}
|
||||
var str = value?.ToString();
|
||||
return str.IsNullOrEmpty() ? defaultValue : double.TryParse(str, out var n) ? n : defaultValue;
|
||||
if (str.IsNullOrEmpty())
|
||||
{
|
||||
return (double)defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return (double)(double.TryParse(str, out var n) ? n : defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -12,6 +12,8 @@
|
||||
|
||||
using SqlSugar;
|
||||
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
@@ -55,12 +57,14 @@ public static class SqlSugarPageExtension
|
||||
/// <param name="whereExpression"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<SqlSugarPagedList<TEntity>> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> queryable,
|
||||
int pageIndex, int pageSize, Func<TEntity, bool> whereExpression = null)
|
||||
int pageIndex, int pageSize, Expression<Func<TEntity, bool>> whereExpression = null)
|
||||
{
|
||||
|
||||
RefAsync<int> totalCount = 0;
|
||||
if (whereExpression != null)
|
||||
queryable = queryable.Where(whereExpression);
|
||||
var records = await queryable.ToPageListAsync(pageIndex, pageSize, totalCount);
|
||||
records = whereExpression != null ? records.Where(whereExpression).ToList() : records;
|
||||
//records = whereExpression != null ? records.Where(whereExpression).ToList() : records;
|
||||
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||
return new SqlSugarPagedList<TEntity>
|
||||
{
|
||||
|
@@ -9,10 +9,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.40" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.40" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.8.8.40" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.96" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.42" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.42" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.8.8.42" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.104" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
<PackageReference Include="MiniExcel" Version="1.31.2" />
|
||||
|
@@ -850,19 +850,19 @@
|
||||
<param name="this"></param>
|
||||
<param name="values"></param>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Admin.Core.JsonExtensions">
|
||||
<member name="T:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions">
|
||||
<summary>
|
||||
对象拓展
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.ToJsonString(System.Object)">
|
||||
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions.ToJsonString(System.Object)">
|
||||
<summary>
|
||||
转换为Json
|
||||
</summary>
|
||||
<param name="item"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.ToJsonWithT``1(System.String)">
|
||||
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions.ToJsonWithT``1(System.String)">
|
||||
<summary>
|
||||
从字符串到json
|
||||
</summary>
|
||||
@@ -1495,7 +1495,7 @@
|
||||
<param name="size"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Admin.Core.SqlSugarPageExtension.ToPagedListAsync``1(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32,System.Func{``0,System.Boolean})">
|
||||
<member name="M:ThingsGateway.Admin.Core.SqlSugarPageExtension.ToPagedListAsync``1(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
|
||||
<summary>
|
||||
SqlSugar分页扩展
|
||||
</summary>
|
||||
|
@@ -61,7 +61,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadRpcLogAsync([FromQuery] RpcLogInput input)
|
||||
{
|
||||
var memoryStream = await _rpcLogService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"rpcLog{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
@@ -76,7 +75,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadBackendLogAsync([FromQuery] BackendLogInput input)
|
||||
{
|
||||
var memoryStream = await _backendLogService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"backendLog{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
@@ -93,7 +91,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadCollectDeviceAsync([FromQuery] CollectDeviceInput input)
|
||||
{
|
||||
var memoryStream = await _collectDeviceService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"collectDevice{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
@@ -108,7 +105,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadUploadDeviceAsync([FromQuery] UploadDeviceInput input)
|
||||
{
|
||||
var memoryStream = await _uploadDeviceService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"uploadDevice{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
@@ -123,7 +119,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadDeviceVariableAsync([FromQuery] DeviceVariableInput input)
|
||||
{
|
||||
var memoryStream = await _variableService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"deviceVariable{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
@@ -138,7 +133,6 @@ public class FileController : IDynamicApiController
|
||||
public async Task<IActionResult> DownloadMemoryVariableAsync([FromQuery] MemoryVariableInput input)
|
||||
{
|
||||
var memoryStream = await _variableService.ExportFileAsync(input);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var data = new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"memoryVariable{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx"
|
||||
|
@@ -89,13 +89,8 @@ public class RpcControler : IDynamicApiController
|
||||
[Description("写入变量")]
|
||||
public async Task<Dictionary<string, OperResult>> WriteDeviceMethods(Dictionary<string, string> objs)
|
||||
{
|
||||
Dictionary<string, OperResult> operResultDict = new();
|
||||
foreach (KeyValuePair<string, string> obj in objs)
|
||||
{
|
||||
var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", obj);
|
||||
operResultDict.Add(obj.Key, result);
|
||||
}
|
||||
return operResultDict;
|
||||
var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", objs);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -80,7 +80,7 @@ public class StringToEncodingConverter : IConverter<string>
|
||||
{
|
||||
try
|
||||
{
|
||||
source = target.ToJson();
|
||||
source = target.ToJsonString();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
|
@@ -72,7 +72,7 @@ public class MemoryVariable : BaseEntity
|
||||
/// <summary>
|
||||
/// 变量额外属性Json,通常使用为上传设备,List属性
|
||||
/// </summary>
|
||||
[SugarColumn(IsJson = true, ColumnName = "VariablePropertys", ColumnDescription = "变量属性Json", IsNullable = true)]
|
||||
[SugarColumn(IsJson = true, ColumnName = "VariablePropertys", ColumnDataType = StaticConfig.CodeFirst_BigString, ColumnDescription = "变量属性Json", IsNullable = true)]
|
||||
[IgnoreExcel]
|
||||
public ConcurrentDictionary<long, List<DependencyProperty>> VariablePropertys { get; set; } = new();
|
||||
/// <summary>
|
||||
|
@@ -65,7 +65,7 @@ public class UploadDevice : BaseEntity
|
||||
/// <summary>
|
||||
/// 设备属性Json
|
||||
/// </summary>
|
||||
[SugarColumn(IsJson = true, ColumnName = "DevicePropertys", ColumnDescription = "设备属性Json", IsNullable = true)]
|
||||
[SugarColumn(IsJson = true, ColumnName = "DevicePropertys", ColumnDataType = StaticConfig.CodeFirst_BigString, ColumnDescription = "设备属性Json", IsNullable = true)]
|
||||
[IgnoreExcel]
|
||||
public List<DependencyProperty> DevicePropertys { get; set; }
|
||||
|
||||
|
@@ -21,7 +21,7 @@ using Newtonsoft.Json.Converters;
|
||||
using System.Dynamic;
|
||||
using System.Text;
|
||||
|
||||
using TouchSocket.Core;
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
|
||||
namespace ThingsGateway.Application;
|
||||
/// <summary>
|
||||
@@ -76,7 +76,7 @@ public class CSharpScriptEngine : ISingleton
|
||||
var expConverter = new ExpandoObjectConverter();
|
||||
dynamic obj = JsonConvert.DeserializeObject<List<ExpandoObject>>(input, expConverter);
|
||||
object result = runscript(obj);
|
||||
var json = result.ToJson();
|
||||
var json = result.ToJsonString();
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ public class CSharpScriptEngine : ISingleton
|
||||
var expConverter = new ExpandoObjectConverter();
|
||||
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(input, expConverter);
|
||||
object result = runscript(obj);
|
||||
var json = result.ToJson();
|
||||
var json = result.ToJsonString();
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public static class CSharpScriptEngineExtension
|
||||
/// </summary>
|
||||
public static string GetSciptListValue<T>(this T datas, string script) where T : class
|
||||
{
|
||||
var inPut = datas.ToJson();
|
||||
var inPut = datas.ToJsonString();
|
||||
if (!string.IsNullOrEmpty(script))
|
||||
{
|
||||
//执行脚本,获取新实体
|
||||
@@ -154,7 +154,7 @@ public static class CSharpScriptEngineExtension
|
||||
/// </summary>
|
||||
public static string GetSciptValue<T>(this T datas, string script) where T : class
|
||||
{
|
||||
var inPut = datas.ToJson();
|
||||
var inPut = datas.ToJsonString();
|
||||
if (!string.IsNullOrEmpty(script))
|
||||
{
|
||||
//执行脚本,获取新实体
|
||||
|
@@ -113,8 +113,9 @@ public class HardwareInfoService : ISingleton
|
||||
try
|
||||
{
|
||||
var url = "http://myip.ipip.net";
|
||||
var stream = await new HttpClient().GetStreamAsync(url);
|
||||
var streamReader = new StreamReader(stream, Encoding.UTF8);
|
||||
using var httpClient = new HttpClient();
|
||||
using var stream = await httpClient.GetStreamAsync(url);
|
||||
using var streamReader = new StreamReader(stream, Encoding.UTF8);
|
||||
var html = streamReader.ReadToEnd();
|
||||
return html.Replace("当前 IP:", "").Replace("来自于:", "");
|
||||
}
|
||||
|
@@ -0,0 +1,197 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
namespace ThingsGateway.Application;
|
||||
|
||||
/// <summary>
|
||||
/// ManageGatewayConfig
|
||||
/// </summary>
|
||||
public class ManageGatewayConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 启用
|
||||
/// </summary>
|
||||
[Description("启用")]
|
||||
public bool Enable { get; set; }
|
||||
/// <summary>
|
||||
/// MqttBrokerIP
|
||||
/// </summary>
|
||||
[Description("Mqtt-Tcp IP")]
|
||||
public string MqttBrokerIP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MqttBrokerPort
|
||||
/// </summary>
|
||||
[Description("Mqtt-Tcp 端口")]
|
||||
public int MqttBrokerPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// UserName
|
||||
/// </summary>
|
||||
[Description("Mqtt用户名")]
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Password
|
||||
/// </summary>
|
||||
[Description("Mqtt密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// WriteRpcTopic,Rpc返回为{WriteRpcTopic}/Return,只有这个topic才开放外部订阅权限
|
||||
/// </summary>
|
||||
[Description("变量写入Rpc主题")]
|
||||
public string WriteRpcTopic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DBDownTopic
|
||||
/// </summary>
|
||||
[Description("配置下发Rpc主题")]
|
||||
public string DBDownTopic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DBUploadTopic
|
||||
/// </summary>
|
||||
[Description("配置上传Rpc主题")]
|
||||
public string DBUploadTopic { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ClientGatewayConfig
|
||||
/// </summary>
|
||||
public class ClientGatewayConfig : ManageGatewayConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
[Description("子网关标识ID")]
|
||||
public string GatewayId { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 用于Mqtt Json传输,上传/下载配置信息
|
||||
/// </summary>
|
||||
public class MqttDBUploadRpcResult
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 采集设备
|
||||
/// </summary>
|
||||
public List<CollectDevice> CollectDevices { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 上传设备
|
||||
/// </summary>
|
||||
public List<UploadDevice> UploadDevices { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 变量
|
||||
/// </summary>
|
||||
public List<DeviceVariable> DeviceVariables { get; set; } = new();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 用于Mqtt Json传输,上传/下载配置信息
|
||||
/// </summary>
|
||||
public class MqttDBDownRpc
|
||||
{
|
||||
/// <summary>
|
||||
/// 采集设备
|
||||
/// </summary>
|
||||
public byte[] CollectDevices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上传设备
|
||||
/// </summary>
|
||||
public byte[] UploadDevices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 变量
|
||||
/// </summary>
|
||||
public byte[] DeviceVariables { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// true=>删除全部后增加
|
||||
/// </summary>
|
||||
[Description("是否删除原采集设备表")]
|
||||
public bool IsCollectDevicesFullUp { get; set; }
|
||||
/// <summary>
|
||||
/// true=>删除全部后增加
|
||||
/// </summary>
|
||||
[Description("是否删除原上传设备表")]
|
||||
public bool IsUploadDevicesFullUp { get; set; }
|
||||
/// <summary>
|
||||
/// true=>删除全部后增加
|
||||
/// </summary>
|
||||
[Description("是否删除原变量表")]
|
||||
public bool IsDeviceVariablesFullUp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否立即重启,使配置生效
|
||||
/// </summary>
|
||||
[Description("是否重启子网关线程")]
|
||||
public bool IsRestart { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// MqttRpc传入
|
||||
/// </summary>
|
||||
public class ManageMqttRpcFrom
|
||||
{
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
public string GatewayId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
public string RpcId { get; set; }
|
||||
/// <summary>
|
||||
/// "WriteInfos":{"test":"1"}
|
||||
/// </summary>
|
||||
public Dictionary<string, string> WriteInfos { get; set; } = new();
|
||||
}
|
||||
/// <summary>
|
||||
/// MqttRpc输出
|
||||
/// </summary>
|
||||
public class ManageMqttRpcResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
public string GatewayId { get; set; }
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
public string RpcId { get; set; }
|
||||
/// <summary>
|
||||
/// 消息
|
||||
/// </summary>
|
||||
public Dictionary<string, OperResult> Message { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
}
|
@@ -0,0 +1,811 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
using Mapster;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
namespace ThingsGateway.Application;
|
||||
|
||||
/// <summary>
|
||||
/// ManageGatewayWorker
|
||||
/// </summary>
|
||||
public class ManageGatewayWorker : BackgroundService
|
||||
{
|
||||
private readonly ILogger _clientLogger;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILogger _manageLogger;
|
||||
/// <summary>
|
||||
/// 全部重启锁
|
||||
/// </summary>
|
||||
private readonly EasyLock restartLock = new();
|
||||
|
||||
private IMqttClient _mqttClient;
|
||||
|
||||
private MqttServer _mqttServer;
|
||||
|
||||
private MqttClientSubscribeOptions _mqttSubscribeOptions;
|
||||
|
||||
/// <inheritdoc cref="ManageGatewayWorker"/>
|
||||
public ManageGatewayWorker(ILoggerFactory loggerFactory)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger("ManageGatewayWorker");
|
||||
_manageLogger = loggerFactory.CreateLogger("管理网关(mqttBroker)");
|
||||
_clientLogger = loggerFactory.CreateLogger("子网关(mqttClient)");
|
||||
}
|
||||
/// <summary>
|
||||
/// 服务状态
|
||||
/// </summary>
|
||||
public OperResult ClientStatuString { get; set; } = new OperResult("初始化");
|
||||
|
||||
/// <summary>
|
||||
/// 服务状态
|
||||
/// </summary>
|
||||
public OperResult ManageStatuString { get; set; } = new OperResult("初始化");
|
||||
#region worker服务
|
||||
/// <inheritdoc/>
|
||||
public override async Task StartAsync(CancellationToken token)
|
||||
{
|
||||
_logger?.LogInformation("ManageGatewayWorker启动");
|
||||
await RestartAsync();
|
||||
await base.StartAsync(token);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task StopAsync(CancellationToken token)
|
||||
{
|
||||
_logger?.LogInformation("ManageGatewayWorker停止");
|
||||
await StopAsync();
|
||||
await base.StopAsync(token);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient != null)
|
||||
{
|
||||
//持续重连
|
||||
var result = await TryMqttClientAsync(stoppingToken);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
_clientLogger.LogDebug("连接正常:" + result.Message);
|
||||
ClientStatuString.ResultCode = ResultCode.Success;
|
||||
ClientStatuString.Message = "连接正常:" + result.Message;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_clientLogger.LogWarning("连接错误:" + result.Message);
|
||||
ClientStatuString.ResultCode = ResultCode.Fail;
|
||||
ClientStatuString.Message = "连接错误:" + result.Message;
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(10000, stoppingToken);
|
||||
|
||||
|
||||
//if (_mqttServer != null)
|
||||
//{
|
||||
// //TODO:test code
|
||||
// var mqttClientStatuses = await _mqttServer.GetClientsAsync();
|
||||
|
||||
// if (mqttClientStatuses.FirstOrDefault() is MqttClientStatus mqttClientStatus)
|
||||
// {
|
||||
// //获取子网关信息
|
||||
// var getClientGatewayDBResult = await GetClientGatewayDBAsync(mqttClientStatus.Id);
|
||||
|
||||
// //下发子网关配置
|
||||
// var mqttDBDownRpc = new MqttDBDownRpc
|
||||
// {
|
||||
// IsRestart = true
|
||||
// };
|
||||
// var setClientGatewayDBResult = await SetClientGatewayDBAsync(mqttClientStatus.Id, mqttDBDownRpc);
|
||||
|
||||
// //下发子网关配置
|
||||
// var manageMqttRpcFrom = new ManageMqttRpcFrom
|
||||
// {
|
||||
// WriteInfos = new Dictionary<string, string>()
|
||||
// {
|
||||
// {
|
||||
// "test41","123"
|
||||
// }
|
||||
// },
|
||||
// GatewayId = "GatewayId",
|
||||
// RpcId = "123456",
|
||||
// };
|
||||
|
||||
// var WriteVariableResult = await WriteVariableAsync(manageMqttRpcFrom);
|
||||
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 获取子网关的配置信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<MqttDBUploadRpcResult>> GetClientGatewayDBAsync(string gatewayId, int timeOut = 3000, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var buffer = Encoding.UTF8.GetBytes(string.Empty);
|
||||
var response = await RpcDataExecuteAsync(gatewayId, ClientGatewayConfig.DBUploadTopic, buffer, timeOut, MqttQualityOfServiceLevel.AtMostOnce, token);
|
||||
var data = Encoding.UTF8.GetString(response).FromJsonString<MqttDBUploadRpcResult>();
|
||||
return OperResult.CreateSuccessResult(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<MqttDBUploadRpcResult>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重启
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task RestartAsync()
|
||||
{
|
||||
await StopAsync();
|
||||
await StartAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RPC请求子网关并返回,需要传入子网关ID,作为Topic参数一部分
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> RpcDataExecuteAsync(string gatewayId, string topic, byte[] payload, int timeOut, MqttQualityOfServiceLevel qualityOfServiceLevel, CancellationToken token = default)
|
||||
{
|
||||
var responseTopic = GetRpcReturnTopic(gatewayId, topic);
|
||||
var requestTopic = GetRpcTopic(gatewayId, topic);
|
||||
|
||||
try
|
||||
{
|
||||
using WaitDataAsync<byte[]> waitDataAsync = new();
|
||||
if (!_waitingCalls.TryAdd(responseTopic, waitDataAsync))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
waitDataAsync.SetCancellationToken(token);
|
||||
|
||||
//请求子网关的数据
|
||||
var message = new MqttApplicationMessageBuilder().WithTopic(requestTopic).WithPayload(payload).Build();
|
||||
await _mqttServer.InjectApplicationMessage(new InjectedMqttApplicationMessage(message), token);
|
||||
|
||||
var result = await waitDataAsync.WaitAsync(timeOut);
|
||||
switch (result)
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
return waitDataAsync.WaitResult;
|
||||
case WaitDataStatus.Overtime:
|
||||
throw new TimeoutException();
|
||||
case WaitDataStatus.Canceled:
|
||||
{
|
||||
throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。");
|
||||
}
|
||||
case WaitDataStatus.Default:
|
||||
case WaitDataStatus.Disposed:
|
||||
default:
|
||||
throw new Exception(ThingsGatewayStatus.UnknownError.GetDescription());
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_waitingCalls.Remove(responseTopic);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载配置信息到子网关
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<OperResult>> SetClientGatewayDBAsync(string gatewayId, MqttDBDownRpc mqttDBRpc, int timeOut = 3000, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var buffer = Encoding.UTF8.GetBytes(mqttDBRpc?.ToJsonString() ?? string.Empty);
|
||||
var response = await RpcDataExecuteAsync(gatewayId, ClientGatewayConfig.DBDownTopic, buffer, timeOut, MqttQualityOfServiceLevel.AtMostOnce, token);
|
||||
var data = Encoding.UTF8.GetString(response).FromJsonString<OperResult>();
|
||||
return OperResult.CreateSuccessResult(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<OperResult>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入变量到子网关
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<ManageMqttRpcResult>> WriteVariableAsync(ManageMqttRpcFrom manageMqttRpcFrom, int timeOut = 3000, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var payload = Encoding.UTF8.GetBytes(manageMqttRpcFrom?.ToJsonString() ?? string.Empty);
|
||||
var requestTopic = ManageGatewayConfig.WriteRpcTopic;
|
||||
var responseTopic = GetRpcReturnTopic(ManageGatewayConfig.WriteRpcTopic);
|
||||
var key = GetRpcReturnIdTopic(manageMqttRpcFrom.GatewayId, requestTopic, manageMqttRpcFrom.RpcId);
|
||||
|
||||
ManageMqttRpcResult result = await RpcWriteExecuteAsync(timeOut, payload, requestTopic, key, token);
|
||||
|
||||
return OperResult.CreateSuccessResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<ManageMqttRpcResult>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取子网关列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<MqttClientStatus>> GetClientGatewayAsync()
|
||||
{
|
||||
var data = await _mqttServer.GetClientsAsync();
|
||||
return data.ToList();
|
||||
}
|
||||
|
||||
|
||||
internal async Task StartAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
//重启操作在未完全之前直接取消
|
||||
if (restartLock.IsWaitting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await restartLock.WaitAsync();
|
||||
|
||||
await InitAsync();
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "启动错误");
|
||||
}
|
||||
finally
|
||||
{
|
||||
restartLock.Release();
|
||||
}
|
||||
}
|
||||
internal async Task StopAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
//重启操作在未完全之前直接取消
|
||||
if (restartLock.IsWaitting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await restartLock.WaitAsync();
|
||||
_mqttClient?.SafeDispose();
|
||||
_mqttServer?.SafeDispose();
|
||||
_mqttClient = null;
|
||||
_mqttServer = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "停止错误");
|
||||
}
|
||||
finally
|
||||
{
|
||||
restartLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region 核心实现
|
||||
readonly ConcurrentDictionary<string, WaitDataAsync<byte[]>> _waitingCalls = new();
|
||||
readonly ConcurrentDictionary<string, WaitDataAsync<ManageMqttRpcResult>> _writerRpcResultWaitingCalls = new();
|
||||
private readonly EasyLock clientLock = new();
|
||||
/// <summary>
|
||||
/// ClientGatewayConfig
|
||||
/// </summary>
|
||||
public ClientGatewayConfig ClientGatewayConfig;
|
||||
/// <summary>
|
||||
/// ManageGatewayConfig
|
||||
/// </summary>
|
||||
public ManageGatewayConfig ManageGatewayConfig;
|
||||
private MqttClientOptions _mqttClientOptions;
|
||||
RpcSingletonService _rpcCore;
|
||||
|
||||
private async Task DBDownTopicMethod(MqttApplicationMessageReceivedEventArgs args)
|
||||
{
|
||||
var mqttDBRpc = args.ApplicationMessage.PayloadSegment.Count > 0 ? Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment).FromJsonString<MqttDBDownRpc>() : null;
|
||||
if (mqttDBRpc != null)
|
||||
{
|
||||
OperResult result = new();
|
||||
var collectDeviceService = App.GetService<CollectDeviceService>();
|
||||
var variableService = App.GetService<VariableService>();
|
||||
var uploadDeviceService = App.GetService<UploadDeviceService>();
|
||||
|
||||
collectDeviceService.Context = variableService.Context = uploadDeviceService.Context;
|
||||
var itenant = collectDeviceService.Context.AsTenant();
|
||||
//事务
|
||||
var dbResult = await itenant.UseTranAsync(async () =>
|
||||
{
|
||||
|
||||
if (mqttDBRpc.IsCollectDevicesFullUp)
|
||||
{
|
||||
await collectDeviceService.AsDeleteable().ExecuteCommandAsync();
|
||||
}
|
||||
var collectDevices = new List<CollectDevice>();
|
||||
|
||||
|
||||
if (mqttDBRpc.CollectDevices != null && mqttDBRpc.CollectDevices.Length > 0)
|
||||
{
|
||||
MemoryStream stream = new(mqttDBRpc.CollectDevices);
|
||||
var previewResult = await collectDeviceService.PreviewAsync(stream);
|
||||
if (previewResult.FirstOrDefault().Value.HasError)
|
||||
{
|
||||
throw new(previewResult.Select(a => a.Value.Results.Where(a => !a.isSuccess).ToList()).ToList().ToJsonString());
|
||||
}
|
||||
foreach (var item in previewResult)
|
||||
{
|
||||
if (item.Key == ExportHelpers.CollectDeviceSheetName)
|
||||
{
|
||||
var collectDeviceImports = ((ImportPreviewOutput<CollectDevice>)item.Value).Data;
|
||||
collectDevices = collectDeviceImports.Values.Adapt<List<CollectDevice>>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
await collectDeviceService.ImportAsync(previewResult);
|
||||
|
||||
}
|
||||
|
||||
if (mqttDBRpc.IsUploadDevicesFullUp)
|
||||
{
|
||||
await uploadDeviceService.AsDeleteable().ExecuteCommandAsync();
|
||||
|
||||
}
|
||||
var uploadDevices = new List<UploadDevice>();
|
||||
|
||||
if (mqttDBRpc.UploadDevices != null && mqttDBRpc.UploadDevices.Length > 0)
|
||||
{
|
||||
MemoryStream stream1 = new(mqttDBRpc.UploadDevices);
|
||||
var previewResult1 = await uploadDeviceService.PreviewAsync(stream1);
|
||||
if (previewResult1.FirstOrDefault().Value.HasError)
|
||||
{
|
||||
throw new(previewResult1.Select(a => a.Value.Results.Where(a => !a.isSuccess).ToList()).ToList().ToJsonString());
|
||||
}
|
||||
foreach (var item in previewResult1)
|
||||
{
|
||||
if (item.Key == ExportHelpers.UploadDeviceSheetName)
|
||||
{
|
||||
var uploadDeviceImports = ((ImportPreviewOutput<UploadDevice>)item.Value).Data;
|
||||
uploadDevices = uploadDeviceImports.Values.Adapt<List<UploadDevice>>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
await uploadDeviceService.ImportAsync(previewResult1);
|
||||
|
||||
}
|
||||
|
||||
if (mqttDBRpc.IsDeviceVariablesFullUp)
|
||||
{
|
||||
await variableService.AsDeleteable().ExecuteCommandAsync();
|
||||
|
||||
}
|
||||
if (mqttDBRpc.DeviceVariables != null && mqttDBRpc.DeviceVariables.Length > 0)
|
||||
{
|
||||
MemoryStream stream2 = new(mqttDBRpc.DeviceVariables);
|
||||
var previewResult2 = await variableService.PreviewAsync(stream2, collectDevices, uploadDevices);
|
||||
if (previewResult2.FirstOrDefault().Value.HasError)
|
||||
{
|
||||
throw new(previewResult2.Select(a => a.Value.Results.Where(a => !a.isSuccess).ToList()).ToList().ToJsonString());
|
||||
}
|
||||
await variableService.ImportAsync(previewResult2);
|
||||
}
|
||||
});
|
||||
CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_CollectDevice);//cache删除
|
||||
CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_UploadDevice);//cache删除
|
||||
|
||||
if (dbResult.IsSuccess)//如果成功了
|
||||
{
|
||||
_clientLogger.LogInformation("子网关接收配置,并保存至数据库-执行成功");
|
||||
result = OperResult.CreateSuccessResult();
|
||||
if (mqttDBRpc.IsRestart)
|
||||
{
|
||||
_clientLogger.LogInformation("子网关接收配置,并重启");
|
||||
await ServiceHelper.GetBackgroundService<CollectDeviceWorker>().RestartDeviceThreadAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写日志
|
||||
result.Message = dbResult.ErrorMessage;
|
||||
}
|
||||
|
||||
var variableMessage = new MqttApplicationMessageBuilder()
|
||||
.WithTopic(GetRpcReturnTopic(args.ApplicationMessage.Topic))
|
||||
.WithPayload(result.ToJsonString()).Build();
|
||||
if (_mqttClient.IsConnected)
|
||||
await _mqttClient.PublishAsync(variableMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DBUploadTopicMethod(MqttApplicationMessageReceivedEventArgs args)
|
||||
{
|
||||
MqttDBUploadRpcResult result = new();
|
||||
var collectDeviceService = App.GetService<CollectDeviceService>();
|
||||
var variableService = App.GetService<VariableService>();
|
||||
var uploadDeviceService = App.GetService<UploadDeviceService>();
|
||||
result.CollectDevices = collectDeviceService.GetCacheList(false);
|
||||
result.DeviceVariables = await variableService.GetListAsync();
|
||||
result.UploadDevices = uploadDeviceService.GetCacheList(false);
|
||||
|
||||
var variableMessage = new MqttApplicationMessageBuilder()
|
||||
.WithTopic(GetRpcReturnTopic(args.ApplicationMessage.Topic))
|
||||
.WithPayload(result.ToJsonString()).Build();
|
||||
if (_mqttClient.IsConnected)
|
||||
await _mqttClient.PublishAsync(variableMessage);
|
||||
}
|
||||
|
||||
private string GetRpcReturnIdTopic(string gatewayId, string topic, string rpcId)
|
||||
{
|
||||
var responseTopic = $"{gatewayId}/{topic}/rpc/Return/rpcId";
|
||||
return responseTopic;
|
||||
}
|
||||
|
||||
private string GetRpcReturnTopic(string gatewayId, string topic)
|
||||
{
|
||||
var responseTopic = $"{gatewayId}/{topic}/rpc/Return";
|
||||
return responseTopic;
|
||||
}
|
||||
|
||||
private string GetRpcReturnTopic(string requestTopic)
|
||||
{
|
||||
var responseTopic = $"{requestTopic}/Return";
|
||||
return responseTopic;
|
||||
}
|
||||
|
||||
private string GetRpcTopic(string gatewayId, string topic)
|
||||
{
|
||||
var requestTopic = $"{gatewayId}/{topic}/rpc";
|
||||
return requestTopic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
private async Task InitAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
ManageGatewayConfig = App.GetConfig<ManageGatewayConfig>("ManageGatewayConfig");
|
||||
if (ManageGatewayConfig?.Enable != true)
|
||||
{
|
||||
ManageStatuString = new OperResult($"已退出:不启用管理功能");
|
||||
_manageLogger.LogWarning("已退出:不启用管理功能");
|
||||
}
|
||||
else
|
||||
{
|
||||
var mqttFactory = new MqttFactory(new MqttNetLogger(_manageLogger));
|
||||
var mqttServerOptions = mqttFactory.CreateServerOptionsBuilder()
|
||||
.WithDefaultEndpointBoundIPAddress(string.IsNullOrEmpty(ManageGatewayConfig.MqttBrokerIP) ? null : IPAddress.Parse(ManageGatewayConfig.MqttBrokerIP))
|
||||
.WithDefaultEndpointPort(ManageGatewayConfig.MqttBrokerPort)
|
||||
.WithDefaultEndpoint()
|
||||
.Build();
|
||||
_mqttServer = mqttFactory.CreateMqttServer(mqttServerOptions);
|
||||
if (_mqttServer != null)
|
||||
{
|
||||
_mqttServer.ValidatingConnectionAsync += MqttServer_ValidatingConnectionAsync;//认证
|
||||
_mqttServer.InterceptingPublishAsync += MqttServer_InterceptingPublishAsync;//认证
|
||||
|
||||
await _mqttServer.StartAsync();
|
||||
}
|
||||
ManageStatuString = OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_manageLogger.LogError(ex, "初始化失败");
|
||||
ManageStatuString = new($"初始化失败-{ex.Message}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ClientGatewayConfig = App.GetConfig<ClientGatewayConfig>("ClientGatewayConfig");
|
||||
if (ClientGatewayConfig?.Enable != true)
|
||||
{
|
||||
ClientStatuString = new OperResult($"已退出:不启用子网关功能");
|
||||
_clientLogger.LogWarning("已退出:不启用子网关功能");
|
||||
}
|
||||
else
|
||||
{
|
||||
var mqttFactory = new MqttFactory(new MqttNetLogger(_clientLogger));
|
||||
_mqttClientOptions = mqttFactory.CreateClientOptionsBuilder()
|
||||
.WithCredentials(ClientGatewayConfig.UserName, ClientGatewayConfig.Password)//账密
|
||||
.WithTcpServer(ClientGatewayConfig.MqttBrokerIP, ClientGatewayConfig.MqttBrokerPort)//服务器
|
||||
.WithClientId(ClientGatewayConfig.GatewayId)
|
||||
.WithCleanSession(true)
|
||||
.WithKeepAlivePeriod(TimeSpan.FromSeconds(120.0))
|
||||
.WithoutThrowOnNonSuccessfulConnectResponse()
|
||||
.Build();
|
||||
_mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
|
||||
.WithTopicFilter(
|
||||
f =>
|
||||
{
|
||||
f.WithTopic(ClientGatewayConfig.WriteRpcTopic);
|
||||
f.WithAtMostOnceQoS();
|
||||
})
|
||||
.WithTopicFilter(
|
||||
f =>
|
||||
{
|
||||
f.WithTopic(GetRpcTopic(ClientGatewayConfig.GatewayId, ClientGatewayConfig.DBDownTopic));
|
||||
f.WithAtMostOnceQoS();
|
||||
})
|
||||
.WithTopicFilter(
|
||||
f =>
|
||||
{
|
||||
f.WithTopic(GetRpcTopic(ClientGatewayConfig.GatewayId, ClientGatewayConfig.DBUploadTopic));
|
||||
f.WithAtMostOnceQoS();
|
||||
})
|
||||
.Build();
|
||||
_mqttClient = mqttFactory.CreateMqttClient();
|
||||
_mqttClient.ConnectedAsync += MqttClient_ConnectedAsync;
|
||||
_mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
|
||||
await TryMqttClientAsync(CancellationToken.None);
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_clientLogger.LogError(ex, "初始化失败");
|
||||
}
|
||||
|
||||
}
|
||||
private async Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs args)
|
||||
{
|
||||
if (args.ApplicationMessage.Topic == GetRpcTopic(ClientGatewayConfig.GatewayId, ClientGatewayConfig.DBUploadTopic))
|
||||
{
|
||||
_clientLogger.LogInformation("子网关配置上传");
|
||||
await DBUploadTopicMethod(args);
|
||||
return;
|
||||
}
|
||||
if (args.ApplicationMessage.Topic == GetRpcTopic(ClientGatewayConfig.GatewayId, ClientGatewayConfig.DBDownTopic))
|
||||
{
|
||||
|
||||
_clientLogger.LogInformation("子网关接收配置,并保存至数据库");
|
||||
await DBDownTopicMethod(args);
|
||||
|
||||
return;
|
||||
}
|
||||
if (args.ApplicationMessage.Topic == ClientGatewayConfig.WriteRpcTopic)
|
||||
{
|
||||
|
||||
await WriteRpcTopicMethod(args);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task MqttClient_ConnectedAsync(MqttClientConnectedEventArgs args)
|
||||
{
|
||||
var subResult = await _mqttClient.SubscribeAsync(_mqttSubscribeOptions);
|
||||
if (subResult.Items.Any(a => a.ResultCode > (MqttClientSubscribeResultCode)10))
|
||||
{
|
||||
_clientLogger?.LogWarning("订阅失败-" + subResult.Items
|
||||
.Where(a => a.ResultCode > (MqttClientSubscribeResultCode)10)
|
||||
.Select(a =>
|
||||
new
|
||||
{
|
||||
Topic = a.TopicFilter.Topic,
|
||||
ResultCode = a.ResultCode.ToString()
|
||||
}
|
||||
)
|
||||
.ToJsonString()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private Task MqttServer_InterceptingPublishAsync(InterceptingPublishEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.ApplicationMessage.Topic == GetRpcReturnTopic(ManageGatewayConfig.WriteRpcTopic))
|
||||
{
|
||||
if (_writerRpcResultWaitingCalls.Count > 0)
|
||||
{
|
||||
var payloadBuffer = eventArgs.ApplicationMessage.PayloadSegment.ToArray();
|
||||
var manageMqttRpcResult = Encoding.UTF8.GetString(payloadBuffer).FromJsonString<ManageMqttRpcResult>();
|
||||
var key = GetRpcReturnIdTopic(manageMqttRpcResult.GatewayId, ManageGatewayConfig.WriteRpcTopic, manageMqttRpcResult.RpcId);
|
||||
if (!_writerRpcResultWaitingCalls.TryRemove(key, out var writeRpcResultAsync))
|
||||
{
|
||||
return CompletedTask.Instance;
|
||||
}
|
||||
writeRpcResultAsync.Set(manageMqttRpcResult);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (!_waitingCalls.TryRemove(eventArgs.ApplicationMessage.Topic, out var awaitable))
|
||||
{
|
||||
return CompletedTask.Instance;
|
||||
}
|
||||
|
||||
var payloadBuffer = eventArgs.ApplicationMessage.PayloadSegment.ToArray();
|
||||
awaitable.Set(payloadBuffer);
|
||||
}
|
||||
|
||||
return CompletedTask.Instance;
|
||||
}
|
||||
|
||||
private Task MqttServer_ValidatingConnectionAsync(ValidatingConnectionEventArgs arg)
|
||||
{
|
||||
if (ManageGatewayConfig.UserName != arg.UserName)
|
||||
{
|
||||
arg.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
|
||||
return CompletedTask.Instance;
|
||||
}
|
||||
if (ManageGatewayConfig.Password != arg.Password)
|
||||
{
|
||||
arg.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
|
||||
return CompletedTask.Instance;
|
||||
}
|
||||
_manageLogger?.LogInformation(ToString() + "-" + arg.ClientId + "-客户端已连接成功");
|
||||
return CompletedTask.Instance;
|
||||
}
|
||||
|
||||
private async Task<OperResult> TryMqttClientAsync(CancellationToken token)
|
||||
{
|
||||
if (_mqttClient?.IsConnected == true)
|
||||
return OperResult.CreateSuccessResult();
|
||||
return await Cilent();
|
||||
|
||||
async Task<OperResult> Cilent()
|
||||
{
|
||||
if (_mqttClient?.IsConnected == true)
|
||||
return OperResult.CreateSuccessResult();
|
||||
try
|
||||
{
|
||||
await clientLock.WaitAsync();
|
||||
if (_mqttClient?.IsConnected == true)
|
||||
return OperResult.CreateSuccessResult();
|
||||
using var timeoutToken = new CancellationTokenSource(TimeSpan.FromMilliseconds(5000));
|
||||
using CancellationTokenSource StoppingToken = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutToken.Token);
|
||||
if (_mqttClient?.IsConnected == true)
|
||||
return OperResult.CreateSuccessResult();
|
||||
if (_mqttClient == null)
|
||||
{
|
||||
return new OperResult("未初始化");
|
||||
}
|
||||
var result = await _mqttClient?.ConnectAsync(_mqttClientOptions, StoppingToken.Token);
|
||||
if (result.ResultCode == MqttClientConnectResultCode.Success)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult(result.ReasonString);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
clientLock.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
private async Task WriteRpcTopicMethod(MqttApplicationMessageReceivedEventArgs args)
|
||||
{
|
||||
var manageMqttRpcFrom = args.ApplicationMessage.PayloadSegment.Count > 0 ? Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment).FromJsonString<ManageMqttRpcFrom>() : null;
|
||||
if (manageMqttRpcFrom != null && manageMqttRpcFrom.GatewayId == ClientGatewayConfig.GatewayId)
|
||||
{
|
||||
ManageMqttRpcResult mqttRpcResult = new() { RpcId = manageMqttRpcFrom.RpcId, GatewayId = manageMqttRpcFrom.GatewayId };
|
||||
_rpcCore ??= App.GetService<RpcSingletonService>();
|
||||
var result = await _rpcCore.InvokeDeviceMethodAsync("子网关RPC" + "-" + args.ClientId,
|
||||
manageMqttRpcFrom.WriteInfos.Where(
|
||||
a => !mqttRpcResult.Message.Any(b => b.Key == a.Key)).ToDictionary(a => a.Key, a => a.Value));
|
||||
mqttRpcResult.Message.AddRange(result);
|
||||
mqttRpcResult.Success = !mqttRpcResult.Message.Any(a => !a.Value.IsSuccess);
|
||||
|
||||
var variableMessage = new MqttApplicationMessageBuilder()
|
||||
.WithTopic(GetRpcReturnTopic(args.ApplicationMessage.Topic))
|
||||
.WithPayload(mqttRpcResult.ToJsonString()).Build();
|
||||
if (_mqttClient.IsConnected)
|
||||
await _mqttClient.PublishAsync(variableMessage);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
private async Task<ManageMqttRpcResult> RpcWriteExecuteAsync(int timeOut, byte[] payload, string requestTopic, string key, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
using WaitDataAsync<ManageMqttRpcResult> waitDataAsync = new();
|
||||
if (!_writerRpcResultWaitingCalls.TryAdd(key, waitDataAsync))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
waitDataAsync.SetCancellationToken(token);
|
||||
|
||||
//请求子网关的数据
|
||||
var message = new MqttApplicationMessageBuilder().WithTopic(requestTopic).WithPayload(payload).Build();
|
||||
await _mqttServer.InjectApplicationMessage(new InjectedMqttApplicationMessage(message), token);
|
||||
|
||||
var result = await waitDataAsync.WaitAsync(timeOut);
|
||||
switch (result)
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
return waitDataAsync.WaitResult;
|
||||
case WaitDataStatus.Overtime:
|
||||
throw new TimeoutException();
|
||||
case WaitDataStatus.Canceled:
|
||||
{
|
||||
throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。");
|
||||
}
|
||||
case WaitDataStatus.Default:
|
||||
case WaitDataStatus.Disposed:
|
||||
default:
|
||||
throw new Exception(ThingsGatewayStatus.UnknownError.GetDescription());
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writerRpcResultWaitingCalls.Remove(key);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
|
||||
namespace ThingsGateway.Application;
|
||||
|
||||
internal class MqttNetLogger : IMqttNetLogger
|
||||
{
|
||||
readonly ILogger LogMessage;
|
||||
public MqttNetLogger(ILogger logger)
|
||||
{
|
||||
LogMessage = logger;
|
||||
}
|
||||
|
||||
public bool IsEnabled => true;
|
||||
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
|
||||
{
|
||||
switch (logLevel)
|
||||
{
|
||||
case MqttNetLogLevel.Verbose:
|
||||
LogMessage?.Log(LogLevel.Trace, source, message != null ? (parameters != null ? message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty : message) : string.Empty, exception);
|
||||
break;
|
||||
|
||||
case MqttNetLogLevel.Info:
|
||||
LogMessage?.Log(LogLevel.Information, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
|
||||
break;
|
||||
|
||||
case MqttNetLogLevel.Warning:
|
||||
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
|
||||
break;
|
||||
|
||||
case MqttNetLogLevel.Error:
|
||||
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -82,18 +82,15 @@ public class DeviceVariableRunTime : DeviceVariable
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="dateTime"></param>
|
||||
public OperResult SetValue(object value, DateTime dateTime = default)
|
||||
/// <param name="isOnline"></param>
|
||||
public OperResult SetValue(object value, DateTime dateTime = default, bool isOnline = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsOnline = isOnline;
|
||||
|
||||
if (value != null)
|
||||
if (!IsOnline)
|
||||
{
|
||||
IsOnline = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsOnline = false;
|
||||
RawValue = value;
|
||||
Set(value);
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -36,6 +38,10 @@ public abstract class CollectBase : DriverBase
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool IsSupportRequest { get; }
|
||||
/// <summary>
|
||||
/// 一般底层驱动,也有可能为null
|
||||
/// </summary>
|
||||
protected abstract IReadWriteDevice PLC { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据转换器
|
||||
@@ -98,9 +104,9 @@ public abstract class CollectBase : DriverBase
|
||||
StopBits = config.StopBits,
|
||||
};
|
||||
FoundataionConfig.SetValue(SerialConfigExtension.SerialProperty, data);
|
||||
var serialClient = new SerialClient();
|
||||
(serialClient).Setup(FoundataionConfig);
|
||||
return OperResult.CreateSuccessResult((object)serialClient);
|
||||
var serialSession = new SerialsSession();
|
||||
(serialSession).Setup(FoundataionConfig);
|
||||
return OperResult.CreateSuccessResult((object)serialSession);
|
||||
case ShareChannelEnum.TcpClientEx:
|
||||
FoundataionConfig.SetRemoteIPHost(new IPHost($"{config.IP}:{config.Port}"));
|
||||
var tcpClient = new TcpClientEx();
|
||||
@@ -153,7 +159,7 @@ public abstract class CollectBase : DriverBase
|
||||
{
|
||||
deviceVariableSourceRead.DeviceVariables.ForEach(it =>
|
||||
{
|
||||
var operResult = it.SetValue(null);
|
||||
var operResult = it.SetValue(null, isOnline: false);
|
||||
if (!operResult.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning("变量值更新失败:" + operResult.Message);
|
||||
@@ -177,10 +183,22 @@ public abstract class CollectBase : DriverBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入变量值
|
||||
/// 批量写入变量值,需返回变量名称/结果
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token);
|
||||
public virtual async Task<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
|
||||
{
|
||||
if (PLC == null)
|
||||
throw new("未初始化成功");
|
||||
Dictionary<string, OperResult> operResults = new();
|
||||
foreach (var writeInfo in writeInfoLists)
|
||||
{
|
||||
var result = await PLC.WriteAsync(writeInfo.Key.VariableAddress, writeInfo.Key.DataType, writeInfo.Value.ToString(), token);
|
||||
await Task.Delay(10, token); //防止密集写入
|
||||
operResults.Add(writeInfo.Key.Name, result);
|
||||
}
|
||||
return operResults;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
@@ -204,6 +222,31 @@ public abstract class CollectBase : DriverBase
|
||||
}
|
||||
}
|
||||
|
||||
internal override void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
|
||||
{
|
||||
if (IsSaveLog)
|
||||
{
|
||||
if (arg3.StartsWith(FoundationConst.LogMessageHeader))
|
||||
{
|
||||
var customLevel = App.GetConfig<Microsoft.Extensions.Logging.LogLevel?>("Logging:LogLevel:BackendLog") ?? Microsoft.Extensions.Logging.LogLevel.Trace;
|
||||
if ((byte)arg1 < (byte)customLevel)
|
||||
{
|
||||
var logRuntime = new BackendLog
|
||||
{
|
||||
LogLevel = (Microsoft.Extensions.Logging.LogLevel)arg1,
|
||||
LogMessage = arg3,
|
||||
LogSource = "采集设备:" + CurDevice.Name,
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
Exception = null,
|
||||
};
|
||||
_logQueues.Enqueue(logRuntime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
base.NewMessage(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回全部内容字节数组
|
||||
/// <br></br>
|
||||
|
@@ -12,7 +12,10 @@
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Extension.ConcurrentQueue;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -40,6 +43,7 @@ public abstract class DriverBase : DisposableObject
|
||||
LogMessage = new LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(Log_Out) { LogLevel = TouchSocket.Core.LogLevel.Trace });
|
||||
FoundataionConfig.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
Task.Factory.StartNew(LogInsertAsync);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
@@ -67,6 +71,12 @@ public abstract class DriverBase : DisposableObject
|
||||
/// </summary>
|
||||
public bool IsLogOut { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否存储报文
|
||||
/// </summary>
|
||||
public bool IsSaveLog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报文信息
|
||||
/// </summary>
|
||||
@@ -82,11 +92,14 @@ public abstract class DriverBase : DisposableObject
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool IsConnected();
|
||||
|
||||
/// <summary>
|
||||
/// 存储日志队列
|
||||
/// </summary>
|
||||
protected ConcurrentQueue<BackendLog> _logQueues = new();
|
||||
/// <summary>
|
||||
/// 设备报文
|
||||
/// </summary>
|
||||
internal void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
|
||||
internal virtual void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
|
||||
{
|
||||
if (IsLogOut)
|
||||
{
|
||||
@@ -102,6 +115,27 @@ public abstract class DriverBase : DisposableObject
|
||||
}
|
||||
|
||||
}
|
||||
private async Task LogInsertAsync()
|
||||
{
|
||||
var db = DbContext.Db.CopyNew();
|
||||
while (!DisposedValue)
|
||||
{
|
||||
if (_logQueues.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = _logQueues.ToListWithDequeue();
|
||||
await db.InsertableWithAttr(data).ExecuteCommandAsync();//入库
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 底层日志输出
|
||||
|
@@ -14,6 +14,8 @@ using Furion;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
namespace ThingsGateway.Application;
|
||||
@@ -153,6 +155,32 @@ public abstract class UpLoadBase : DriverBase
|
||||
_logger.Log_Out(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
}
|
||||
|
||||
internal override void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
|
||||
{
|
||||
if (IsSaveLog)
|
||||
{
|
||||
if (arg3.StartsWith(FoundationConst.LogMessageHeader))
|
||||
{
|
||||
var customLevel = App.GetConfig<Microsoft.Extensions.Logging.LogLevel?>("Logging:LogLevel:BackendLog") ?? Microsoft.Extensions.Logging.LogLevel.Trace;
|
||||
if ((byte)arg1 < (byte)customLevel)
|
||||
{
|
||||
var logRuntime = new BackendLog
|
||||
{
|
||||
LogLevel = (Microsoft.Extensions.Logging.LogLevel)arg1,
|
||||
LogMessage = arg3,
|
||||
LogSource = "上传设备:" + CurDevice.Name,
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
Exception = null,
|
||||
};
|
||||
_logQueues.Enqueue(logRuntime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
base.NewMessage(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -19,6 +19,7 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.Admin.Core.JsonExtensions;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Extension.ConcurrentQueue;
|
||||
|
||||
@@ -48,92 +49,172 @@ public class RpcSingletonService : ISingleton
|
||||
/// 反向RPC入口方法
|
||||
/// </summary>
|
||||
/// <param name="sourceDes">触发该方法的源说明</param>
|
||||
/// <param name="item">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
/// <param name="items">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
/// <param name="isBlazor">如果是true,不检查<see cref="MemoryVariable.RpcWriteEnable"/>字段</param>
|
||||
/// <param name="token"><see cref="CancellationToken"/> 取消源</param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> InvokeDeviceMethodAsync(string sourceDes, KeyValuePair<string, string> item, bool isBlazor = false, CancellationToken token = default)
|
||||
public async Task<Dictionary<string, OperResult>> InvokeDeviceMethodAsync(string sourceDes, Dictionary<string, string> items, bool isBlazor = false, CancellationToken token = default)
|
||||
{
|
||||
//避免并发过高,这里延时10ms
|
||||
await Task.Delay(10, token);
|
||||
OperResult data = new();
|
||||
var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key);
|
||||
if (tag == null) return new OperResult("不存在变量:" + item.Key);
|
||||
if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly) return new OperResult("只读变量");
|
||||
if (!tag.RpcWriteEnable && !isBlazor) return new OperResult("不允许远程写入");
|
||||
|
||||
if (tag.IsMemoryVariable == true)
|
||||
Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, JToken>> WriteVariables = new();
|
||||
Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, string>> WriteMethods = new();
|
||||
Dictionary<string, OperResult> results = new();
|
||||
foreach (var item in items)
|
||||
{
|
||||
return tag.SetValue(item.Value);
|
||||
}
|
||||
var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId);
|
||||
if (dev == null) return new OperResult("系统错误,不存在对应采集设备,请稍候重试");
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine) return new OperResult("设备已离线");
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause) return new OperResult("设备已暂停");
|
||||
if (string.IsNullOrEmpty(tag.OtherMethod))
|
||||
{
|
||||
//写入变量
|
||||
JToken tagValue;
|
||||
try
|
||||
{
|
||||
tagValue = JToken.Parse(item.Value);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
tagValue = JToken.Parse("\"" + item.Value + "\"");
|
||||
}
|
||||
|
||||
data = await dev.InVokeWriteAsync(tag, tagValue, token);
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
OperResult data = new();
|
||||
var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key);
|
||||
if (tag == null)
|
||||
results.Add(item.Key, new("不存在变量:" + item.Key));
|
||||
if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly)
|
||||
results.Add(item.Key, new("只读变量:" + item.Key));
|
||||
if (!tag.RpcWriteEnable && !isBlazor)
|
||||
results.Add(item.Key, new("不允许远程写入:" + item.Key));
|
||||
|
||||
if (tag.IsMemoryVariable == true)
|
||||
{
|
||||
results.Add(item.Key, tag.SetValue(item.Value));
|
||||
}
|
||||
var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId);
|
||||
if (dev == null)
|
||||
results.Add(item.Key, new OperResult("系统错误,不存在对应采集设备,请稍候重试"));
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine)
|
||||
results.Add(item.Key, new OperResult("设备已离线"));
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause)
|
||||
results.Add(item.Key, new OperResult("设备已暂停"));
|
||||
|
||||
if (!results.ContainsKey(item.Key))
|
||||
{
|
||||
if (string.IsNullOrEmpty(tag.OtherMethod))
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = data.Exception,
|
||||
IsSuccess = data.IsSuccess,
|
||||
OperateMethod = WriteVariable,
|
||||
OperateObject = tag.Name,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = item.Value,
|
||||
ResultJson = data.Message
|
||||
//写入变量
|
||||
JToken tagValue;
|
||||
try
|
||||
{
|
||||
tagValue = JToken.Parse(item.Value);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
tagValue = JToken.Parse("\"" + item.Value + "\"");
|
||||
}
|
||||
if (WriteVariables.ContainsKey(dev))
|
||||
{
|
||||
|
||||
WriteVariables[dev].Add(tag, tagValue);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteVariables.Add(dev, new());
|
||||
WriteVariables[dev].Add(tag, tagValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WriteMethods.ContainsKey(dev))
|
||||
{
|
||||
|
||||
WriteMethods[dev].Add(tag, item.Value);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteVariables.Add(dev, new());
|
||||
WriteVariables[dev].Add(tag, item.Value);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (!data.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"写入变量[{tag.Name}]失败:{data.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
foreach (var item in WriteVariables)
|
||||
{
|
||||
//执行变量附带的方法
|
||||
var method = dev.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == tag);
|
||||
try
|
||||
{
|
||||
data = await dev.InvokeMethodAsync(method, false, item.Value, token);
|
||||
var result = await item.Key.InVokeWriteAsync(item.Value, token);
|
||||
foreach (var resultItem in result)
|
||||
{
|
||||
string operObj;
|
||||
string parJson;
|
||||
if (resultItem.Key.IsNullOrEmpty())
|
||||
{
|
||||
operObj = items.Select(x => x.Key).ToJsonString();
|
||||
parJson = items.Select(x => x.Value).ToJsonString();
|
||||
}
|
||||
else
|
||||
{
|
||||
operObj = resultItem.Key;
|
||||
parJson = items[resultItem.Key];
|
||||
|
||||
}
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = resultItem.Value.Exception,
|
||||
IsSuccess = resultItem.Value.IsSuccess,
|
||||
OperateMethod = WriteVariable,
|
||||
OperateObject = operObj,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = parJson,
|
||||
ResultJson = resultItem.Value.Message
|
||||
}
|
||||
);
|
||||
if (!resultItem.Value.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"写入变量[{resultItem.Key}]失败:{resultItem.Value.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
results.AddRange(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
data = new OperResult<string>(ex);
|
||||
}
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = data.Exception,
|
||||
IsSuccess = data.IsSuccess,
|
||||
OperateMethod = tag.OtherMethod,
|
||||
OperateObject = tag.Name,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = item.Value?.ToString(),
|
||||
ResultJson = data.Message
|
||||
}
|
||||
);
|
||||
if (!data.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"执行变量[{tag.Name}]方法[{tag.OtherMethod}]失败:{data.Message}");
|
||||
_logger.LogWarning($"写入变量异常:{ex.Message + Environment.NewLine + ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
return data;
|
||||
foreach (var item in WriteMethods)
|
||||
{
|
||||
foreach (var writeMethod in item.Value)
|
||||
{
|
||||
|
||||
//执行变量附带的方法
|
||||
var method = item.Key.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == writeMethod.Key);
|
||||
OperResult<string> result;
|
||||
try
|
||||
{
|
||||
result = await item.Key.InvokeMethodAsync(method, false, writeMethod.Value, token);
|
||||
results.Add(writeMethod.Key.Name, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = new OperResult<string>(ex);
|
||||
results.Add(writeMethod.Key.Name, result);
|
||||
}
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = result.Exception,
|
||||
IsSuccess = result.IsSuccess,
|
||||
OperateMethod = writeMethod.Key.OtherMethod,
|
||||
OperateObject = writeMethod.Key.Name,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = writeMethod.Value?.ToString(),
|
||||
ResultJson = result.Message
|
||||
}
|
||||
);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"执行变量[{writeMethod.Key.Name}]方法[{writeMethod.Key.OtherMethod}]失败:{result.Message}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async Task RpcLogInsertAsync()
|
||||
{
|
||||
|
@@ -22,6 +22,9 @@ public class DriverPluginSeedData : ISqlSugarEntitySeedData<DriverPlugin>
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<DriverPlugin> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<DriverPlugin>("driver_plugin.json");
|
||||
return SeedDataUtil.GetSeedData<DriverPlugin>("driver_plugin.json")
|
||||
.Concat(SeedDataUtil.GetSeedData<DriverPlugin>("pro_driver_plugin.json"))
|
||||
.Concat(SeedDataUtil.GetSeedData<DriverPlugin>("custom_driver_plugin.json"))
|
||||
;
|
||||
}
|
||||
}
|
@@ -319,6 +319,39 @@
|
||||
"UpdateUserId": null,
|
||||
"SortCode": 0,
|
||||
"ExtJson": null
|
||||
},
|
||||
|
||||
{
|
||||
"Id": 442505,
|
||||
"FileName": "ThingsGateway.DLT645",
|
||||
"AssembleName": "DLT645_2007",
|
||||
"DriverTypeEnum": "Collect",
|
||||
"FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll",
|
||||
"CreateTime": "2023/8/6 18:22:33",
|
||||
"CreateUser": "superAdmin",
|
||||
"CreateUserId": 212725263002001,
|
||||
"IsDelete": 0,
|
||||
"UpdateTime": null,
|
||||
"UpdateUser": null,
|
||||
"UpdateUserId": null,
|
||||
"SortCode": 0,
|
||||
"ExtJson": null
|
||||
},
|
||||
{
|
||||
"Id": 442506,
|
||||
"FileName": "ThingsGateway.DLT645",
|
||||
"AssembleName": "DLT645_2007OverTcp",
|
||||
"DriverTypeEnum": "Collect",
|
||||
"FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll",
|
||||
"CreateTime": "2023/8/6 18:22:33",
|
||||
"CreateUser": "superAdmin",
|
||||
"CreateUserId": 212725263002001,
|
||||
"IsDelete": 0,
|
||||
"UpdateTime": null,
|
||||
"UpdateUser": null,
|
||||
"UpdateUserId": null,
|
||||
"SortCode": 0,
|
||||
"ExtJson": null
|
||||
}
|
||||
]
|
||||
}
|
@@ -95,6 +95,23 @@
|
||||
"UpdateUser": "superAdmin",
|
||||
"UpdateUserId": "212725263002001"
|
||||
},
|
||||
{
|
||||
"Id": "200001904",
|
||||
"Title": "管理网关",
|
||||
"Icon": "mdi-database-sync-outline",
|
||||
"Component": "/gatewayconfig/manage",
|
||||
"Category": "MENU",
|
||||
"ParentId": "200001",
|
||||
"SortCode": "3",
|
||||
"TargetType": "SELF",
|
||||
"CreateTime": "2023-02-26 01:02:12.089",
|
||||
"CreateUser": "superAdmin",
|
||||
"CreateUserId": "212725263002001",
|
||||
"IsDelete": false,
|
||||
"UpdateTime": "2023-03-03 18:01:49.2309339",
|
||||
"UpdateUser": "superAdmin",
|
||||
"UpdateUserId": "212725263002001"
|
||||
},
|
||||
{
|
||||
"Id": "200001004",
|
||||
"Title": "运行状态",
|
||||
|
@@ -22,6 +22,6 @@ public class OpenApiUserSeedData : ISqlSugarEntitySeedData<OpenApiUser>
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<OpenApiUser> SeedData()
|
||||
{
|
||||
return SeedDataUtil.GetSeedData<OpenApiUser>("gatewayopenapi_user.json");
|
||||
return SeedDataUtil.GetSeedData<OpenApiUser>("gateway_openapi_user.json");
|
||||
}
|
||||
}
|
@@ -360,6 +360,8 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
@@ -367,10 +369,17 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
||||
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile file)
|
||||
{
|
||||
_fileService.ImportVerification(file);
|
||||
using var fs = new MemoryStream();
|
||||
using var stream = file.OpenReadStream(512000000);
|
||||
await stream.CopyToAsync(fs);
|
||||
var sheetNames = MiniExcel.GetSheetNames(fs);
|
||||
using var stream = new MemoryStream();
|
||||
using var fs = file.OpenReadStream(512000000);
|
||||
await fs.CopyToAsync(stream);
|
||||
return await PreviewAsync(stream);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(MemoryStream stream)
|
||||
{
|
||||
var sheetNames = MiniExcel.GetSheetNames(stream);
|
||||
var deviceDicts = GetCacheList(false).ToDictionary(a => a.Name);
|
||||
var pluginDicts = _driverPluginService.GetCacheList(false).ToDictionary(a => a.AssembleName);
|
||||
|
||||
@@ -381,7 +390,7 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
||||
foreach (var sheetName in sheetNames)
|
||||
{
|
||||
//单页数据
|
||||
var rows = fs.Query(useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
|
||||
var rows = stream.Query(useHeaderRow: true, sheetName: sheetName).Cast<IDictionary<string, object>>();
|
||||
#region 采集设备sheet
|
||||
if (sheetName == ExportHelpers.CollectDeviceSheetName)
|
||||
{
|
||||
@@ -496,8 +505,7 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ImportPreviews;
|
||||
return Task.FromResult(ImportPreviews);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -63,6 +63,7 @@ public class BackendLogService : DbRepository<BackendLog>, IBackendLogService
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
@@ -86,6 +87,8 @@ public class BackendLogService : DbRepository<BackendLog>, IBackendLogService
|
||||
private ISugarQueryable<BackendLog> GetPage(BackendLogPageInput input)
|
||||
{
|
||||
var query = Context.Queryable<BackendLog>()
|
||||
.WhereIF(input.StartTime != null, a => a.LogTime >= input.StartTime.Value.ToLocalTime())
|
||||
.WhereIF(input.EndTime != null, a => a.LogTime <= input.EndTime.Value.ToLocalTime())
|
||||
.WhereIF(!string.IsNullOrEmpty(input.Source), it => it.LogSource.Contains(input.Source))
|
||||
.WhereIF(!string.IsNullOrEmpty(input.Level), it => it.LogLevel.ToString().Contains(input.Level));
|
||||
for (int i = 0; i < input.SortField.Count; i++)
|
||||
|
@@ -19,6 +19,15 @@ namespace ThingsGateway.Application;
|
||||
/// </summary>
|
||||
public class BackendLogPageInput : BasePageInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public DateTime? StartTime { get; set; } = DateTime.UtcNow.AddDays(-1);
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public DateTime? EndTime { get; set; } = DateTime.UtcNow.AddDays(1);
|
||||
|
||||
/// <summary>
|
||||
/// 日志源
|
||||
/// </summary>
|
||||
@@ -55,6 +64,14 @@ public class BackendLogInput
|
||||
/// </summary>
|
||||
public class RpcLogPageInput : BasePageInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public DateTime? StartTime { get; set; } = DateTime.UtcNow.AddDays(-1);
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public DateTime? EndTime { get; set; } = DateTime.UtcNow.AddDays(1);
|
||||
/// <summary>
|
||||
/// 操作源
|
||||
/// </summary>
|
||||
|
@@ -44,6 +44,8 @@ public class RpcLogService : DbRepository<RpcLog>, IRpcLogService
|
||||
private ISugarQueryable<RpcLog> GetPage(RpcLogPageInput input)
|
||||
{
|
||||
var query = Context.Queryable<RpcLog>()
|
||||
.WhereIF(input.StartTime != null, a => a.LogTime >= input.StartTime.Value.ToLocalTime())
|
||||
.WhereIF(input.EndTime != null, a => a.LogTime <= input.EndTime.Value.ToLocalTime())
|
||||
.WhereIF(!string.IsNullOrEmpty(input.Source), it => it.OperateSource.Contains(input.Source))
|
||||
.WhereIF(!string.IsNullOrEmpty(input.Object), it => it.OperateObject.Contains(input.Object))
|
||||
.WhereIF(!string.IsNullOrEmpty(input.Method), it => it.OperateMethod.Contains(input.Method));
|
||||
@@ -88,6 +90,7 @@ public class RpcLogService : DbRepository<RpcLog>, IRpcLogService
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
|
@@ -64,10 +64,10 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
||||
[OperDesc("复制上传设备")]
|
||||
public async Task CopyDevAsync(IEnumerable<UploadDevice> input)
|
||||
{
|
||||
var newId = YitIdHelper.NextId();
|
||||
var newDevs = input.Adapt<List<UploadDevice>>();
|
||||
newDevs.ForEach(a =>
|
||||
{
|
||||
var newId = YitIdHelper.NextId();
|
||||
a.Id = newId;
|
||||
a.Name = "Copy-" + a.Name + "-" + newId.ToString();
|
||||
});
|
||||
@@ -284,6 +284,7 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
@@ -305,15 +306,19 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
||||
CacheStatic.Cache.Remove(ThingsGatewayCacheConst.Cache_UploadDevice);//cache删除
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile file)
|
||||
{
|
||||
_fileService.ImportVerification(file);
|
||||
using var fs = new MemoryStream();
|
||||
using var stream = file.OpenReadStream(512000000);
|
||||
await stream.CopyToAsync(fs);
|
||||
var sheetNames = MiniExcel.GetSheetNames(fs);
|
||||
using var stream = new MemoryStream();
|
||||
using var fs = file.OpenReadStream(512000000);
|
||||
await fs.CopyToAsync(stream);
|
||||
return await PreviewAsync(stream);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(MemoryStream stream)
|
||||
{
|
||||
var sheetNames = MiniExcel.GetSheetNames(stream);
|
||||
var deviceDicts = GetCacheList(false).ToDictionary(a => a.Name);
|
||||
var pluginDicts = _driverPluginService.GetCacheList(false).ToDictionary(a => a.AssembleName);
|
||||
|
||||
@@ -324,7 +329,7 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
||||
foreach (var sheetName in sheetNames)
|
||||
{
|
||||
//单页数据
|
||||
var rows = (fs.Query(useHeaderRow: true, sheetName: sheetName)).Cast<IDictionary<string, object>>();
|
||||
var rows = (stream.Query(useHeaderRow: true, sheetName: sheetName)).Cast<IDictionary<string, object>>();
|
||||
#region 上传设备sheet
|
||||
if (sheetName == ExportHelpers.UploadDeviceSheetName)
|
||||
{
|
||||
@@ -434,7 +439,7 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
||||
|
||||
|
||||
|
||||
return ImportPreviews;
|
||||
return Task.FromResult(ImportPreviews);
|
||||
}
|
||||
#endregion
|
||||
}
|
@@ -129,11 +129,11 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
{
|
||||
uploadDevid = _uploadDeviceService.GetIdByName(input.UploadDeviceName);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(input.UploadDeviceName))
|
||||
{
|
||||
var pageInfo = await query.ToPagedListAsync(input.Current, input.Size, a => a.VariablePropertys.ContainsKey(uploadDevid ?? 0));//分页
|
||||
var pageInfo = await query.ToPagedListAsync(input.Current, input.Size, a => SqlFunc.JsonLike(a.VariablePropertys, uploadDevid.ToString()));//分页
|
||||
return pageInfo;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -313,6 +313,7 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
@@ -406,6 +407,7 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await memoryStream.SaveAsAsync(sheets);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
@@ -571,15 +573,21 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
return ImportPreviews;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile file)
|
||||
{
|
||||
_fileService.ImportVerification(file);
|
||||
using var fs = new MemoryStream();
|
||||
using var stream = file.OpenReadStream(512000000);
|
||||
await stream.CopyToAsync(fs);
|
||||
var sheetNames = MiniExcel.GetSheetNames(fs);
|
||||
using var stream = new MemoryStream();
|
||||
using var fs = file.OpenReadStream(512000000);
|
||||
await fs.CopyToAsync(stream);
|
||||
return await PreviewAsync(stream);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(MemoryStream stream, List<CollectDevice> memCollectDevices = null, List<UploadDevice> memUploadDevices = null)
|
||||
{
|
||||
|
||||
var sheetNames = MiniExcel.GetSheetNames(stream);
|
||||
|
||||
var dbVariables = await Context.Queryable<DeviceVariable>().Select(it => new { it.Id, it.Name }).ToListAsync();
|
||||
//转为字典,提高查找效率
|
||||
@@ -591,7 +599,7 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
foreach (var sheetName in sheetNames)
|
||||
{
|
||||
//单页数据
|
||||
var rows = fs.Query(useHeaderRow: true, sheetName: sheetName, configuration: new OpenXmlConfiguration { EnableSharedStringCache = false })
|
||||
var rows = stream.Query(useHeaderRow: true, sheetName: sheetName, configuration: new OpenXmlConfiguration { EnableSharedStringCache = false })
|
||||
.Cast<IDictionary<string, object>>();
|
||||
|
||||
if (sheetName == ExportHelpers.DeviceVariableSheetName)
|
||||
@@ -600,7 +608,10 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
ImportPreviewOutput<DeviceVariable> importPreviewOutput = new();
|
||||
ImportPreviews.Add(sheetName, importPreviewOutput);
|
||||
deviceImportPreview = importPreviewOutput;
|
||||
var cacheDeviceDicts = _collectDeviceService.GetCacheList(false).ToDictionary(a => a.Name);
|
||||
|
||||
var cacheDeviceDicts = memCollectDevices == null ? _collectDeviceService.GetCacheList(false).ToDictionary(a => a.Name) :
|
||||
_collectDeviceService.GetCacheList(false).Concat(memCollectDevices).ToDictionary(a => a.Name)
|
||||
;
|
||||
//线程安全
|
||||
var variables = new ConcurrentList<DeviceVariable>();
|
||||
//并行注意线程安全
|
||||
@@ -679,7 +690,9 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
.Where(a => a.GetCustomAttribute<VariablePropertyAttribute>() != null)
|
||||
.ToDictionary(a => a.FindDisplayAttribute(a => a.GetCustomAttribute<VariablePropertyAttribute>()?.Description));
|
||||
|
||||
var cacheUpdeviceDicts = _uploadDeviceService.GetCacheList(false).ToDictionary(a => a.Name);
|
||||
var cacheUpdeviceDicts = memUploadDevices == null ? _uploadDeviceService.GetCacheList(false).ToDictionary(a => a.Name) :
|
||||
_uploadDeviceService.GetCacheList(false).Concat(memUploadDevices).ToDictionary(a => a.Name)
|
||||
;
|
||||
rows.ParallelForEach(item =>
|
||||
{
|
||||
try
|
||||
|
@@ -44,6 +44,7 @@ public class Startup : AppStartup
|
||||
services.AddHostedService<AlarmWorker>();
|
||||
services.AddHostedService<HistoryValueWorker>();
|
||||
services.AddHostedService<UploadDeviceWorker>();
|
||||
services.AddHostedService<ManageGatewayWorker>();
|
||||
}
|
||||
|
||||
}
|
@@ -6,7 +6,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="SeedData\Json\driver_plugin.json" />
|
||||
<None Remove="SeedData\Json\gatewayopenapi_user.json" />
|
||||
<None Remove="SeedData\Json\gateway_openapi_user.json" />
|
||||
<None Remove="SeedData\Json\gateway_relation.json" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<Content Include="SeedData\Json\gateway_resource.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="SeedData\Json\gatewayopenapi_user.json">
|
||||
<Content Include="SeedData\Json\gateway_openapi_user.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="SeedData\Json\gateway_relation.json">
|
||||
@@ -37,7 +37,8 @@
|
||||
<PackageReference Include="Hardware.Info" Version="11.1.1.1" />
|
||||
<PackageReference Include="CS-Script" Version="4.8.1" />
|
||||
<!--CS-Script与Furion冲突,直接安装覆盖版本-->
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.6.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.7.0" />
|
||||
<PackageReference Include="MQTTnet" Version="4.2.1.781" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -1397,6 +1397,249 @@
|
||||
<member name="M:ThingsGateway.Application.BackendLogDatabaseLoggingWriter.Write(Furion.Logging.LogMessage,System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.ManageGatewayConfig">
|
||||
<summary>
|
||||
ManageGatewayConfig
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.Enable">
|
||||
<summary>
|
||||
启用
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.MqttBrokerIP">
|
||||
<summary>
|
||||
MqttBrokerIP
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.MqttBrokerPort">
|
||||
<summary>
|
||||
MqttBrokerPort
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.UserName">
|
||||
<summary>
|
||||
UserName
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.Password">
|
||||
<summary>
|
||||
Password
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.WriteRpcTopic">
|
||||
<summary>
|
||||
WriteRpcTopic,Rpc返回为{WriteRpcTopic}/Return,只有这个topic才开放外部订阅权限
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.DBDownTopic">
|
||||
<summary>
|
||||
DBDownTopic
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayConfig.DBUploadTopic">
|
||||
<summary>
|
||||
DBUploadTopic
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.ClientGatewayConfig">
|
||||
<summary>
|
||||
ClientGatewayConfig
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ClientGatewayConfig.GatewayId">
|
||||
<summary>
|
||||
标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.MqttDBUploadRpcResult">
|
||||
<summary>
|
||||
用于Mqtt Json传输,上传/下载配置信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBUploadRpcResult.CollectDevices">
|
||||
<summary>
|
||||
采集设备
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBUploadRpcResult.UploadDevices">
|
||||
<summary>
|
||||
上传设备
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBUploadRpcResult.DeviceVariables">
|
||||
<summary>
|
||||
变量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.MqttDBDownRpc">
|
||||
<summary>
|
||||
用于Mqtt Json传输,上传/下载配置信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBDownRpc.CollectDevices">
|
||||
<summary>
|
||||
采集设备
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBDownRpc.UploadDevices">
|
||||
<summary>
|
||||
上传设备
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBDownRpc.DeviceVariables">
|
||||
<summary>
|
||||
变量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBDownRpc.IsCollectDevicesFullUp">
|
||||
<summary>
|
||||
true=>删除全部后增加
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBDownRpc.IsUploadDevicesFullUp">
|
||||
<summary>
|
||||
true=>删除全部后增加
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBDownRpc.IsDeviceVariablesFullUp">
|
||||
<summary>
|
||||
true=>删除全部后增加
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MqttDBDownRpc.IsRestart">
|
||||
<summary>
|
||||
是否立即重启,使配置生效
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.ManageMqttRpcFrom">
|
||||
<summary>
|
||||
MqttRpc传入
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageMqttRpcFrom.GatewayId">
|
||||
<summary>
|
||||
标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageMqttRpcFrom.RpcId">
|
||||
<summary>
|
||||
标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageMqttRpcFrom.WriteInfos">
|
||||
<summary>
|
||||
"WriteInfos":{"test":"1"}
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.ManageMqttRpcResult">
|
||||
<summary>
|
||||
MqttRpc输出
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.GatewayId">
|
||||
<summary>
|
||||
标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.RpcId">
|
||||
<summary>
|
||||
标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.Message">
|
||||
<summary>
|
||||
消息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageMqttRpcResult.Success">
|
||||
<summary>
|
||||
是否成功
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.ManageGatewayWorker">
|
||||
<summary>
|
||||
ManageGatewayWorker
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Application.ManageGatewayWorker.restartLock">
|
||||
<summary>
|
||||
全部重启锁
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.#ctor(Microsoft.Extensions.Logging.ILoggerFactory)">
|
||||
<inheritdoc cref="T:ThingsGateway.Application.ManageGatewayWorker"/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayWorker.ClientStatuString">
|
||||
<summary>
|
||||
服务状态
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.ManageGatewayWorker.ManageStatuString">
|
||||
<summary>
|
||||
服务状态
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.StartAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.StopAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.ExecuteAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.GetClientGatewayDBAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
获取子网关的配置信息
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.RestartAsync">
|
||||
<summary>
|
||||
重启
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.RpcDataExecuteAsync(System.String,System.String,System.Byte[],System.Int32,MQTTnet.Protocol.MqttQualityOfServiceLevel,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
RPC请求子网关并返回,需要传入子网关ID,作为Topic参数一部分
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.SetClientGatewayDBAsync(System.String,ThingsGateway.Application.MqttDBDownRpc,System.Int32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
下载配置信息到子网关
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.WriteVariableAsync(ThingsGateway.Application.ManageMqttRpcFrom,System.Int32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
写入变量到子网关
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.GetClientGatewayAsync">
|
||||
<summary>
|
||||
获取子网关列表
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Application.ManageGatewayWorker.ClientGatewayConfig">
|
||||
<summary>
|
||||
ClientGatewayConfig
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Application.ManageGatewayWorker.ManageGatewayConfig">
|
||||
<summary>
|
||||
ManageGatewayConfig
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.ManageGatewayWorker.InitAsync">
|
||||
<summary>
|
||||
初始化
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.CollectDeviceRunTime">
|
||||
<summary>
|
||||
采集设备状态表示
|
||||
@@ -1601,12 +1844,13 @@
|
||||
最近一次值
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.DeviceVariableRunTime.SetValue(System.Object,System.DateTime)">
|
||||
<member name="M:ThingsGateway.Application.DeviceVariableRunTime.SetValue(System.Object,System.DateTime,System.Boolean)">
|
||||
<summary>
|
||||
设置变量值与时间,设置为null时只更改质量戳状态
|
||||
</summary>
|
||||
<param name="value"></param>
|
||||
<param name="dateTime"></param>
|
||||
<param name="isOnline"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.DeviceVariableRunTime.ChangeTime">
|
||||
<summary>
|
||||
@@ -1855,6 +2099,11 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.CollectBase.PLC">
|
||||
<summary>
|
||||
一般底层驱动,也有可能为null
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.CollectBase.ThingsGatewayBitConverter">
|
||||
<summary>
|
||||
数据转换器
|
||||
@@ -1906,9 +2155,9 @@
|
||||
采集驱动读取
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectBase.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.Application.CollectBase.WriteValuesAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
写入变量值
|
||||
批量写入变量值,需返回变量名称/结果
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
@@ -1972,6 +2221,11 @@
|
||||
是否输出日志
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.DriverBase.IsSaveLog">
|
||||
<summary>
|
||||
是否存储报文
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.DriverBase.Messages">
|
||||
<summary>
|
||||
报文信息
|
||||
@@ -1988,6 +2242,11 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Application.DriverBase._logQueues">
|
||||
<summary>
|
||||
存储日志队列
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.DriverBase.NewMessage(TouchSocket.Core.LogLevel,System.Object,System.String,System.Exception)">
|
||||
<summary>
|
||||
设备报文
|
||||
@@ -2242,12 +2501,12 @@
|
||||
<member name="M:ThingsGateway.Application.RpcSingletonService.#ctor(Microsoft.Extensions.Logging.ILogger{ThingsGateway.Application.RpcSingletonService})">
|
||||
<inheritdoc cref="T:ThingsGateway.Application.RpcSingletonService"/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.KeyValuePair{System.String,System.String},System.Boolean,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.Dictionary{System.String,System.String},System.Boolean,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
反向RPC入口方法
|
||||
</summary>
|
||||
<param name="sourceDes">触发该方法的源说明</param>
|
||||
<param name="item">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
<param name="items">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
<param name="isBlazor">如果是true,不检查<see cref="P:ThingsGateway.Application.MemoryVariable.RpcWriteEnable"/>字段</param>
|
||||
<param name="token"><see cref="T:System.Threading.CancellationToken"/> 取消源</param>
|
||||
<returns></returns>
|
||||
@@ -2346,6 +2605,9 @@
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceService.PreviewAsync(Microsoft.AspNetCore.Components.Forms.IBrowserFile)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceService.PreviewAsync(System.IO.MemoryStream)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceService.ImportAsync(System.Collections.Generic.Dictionary{System.String,ThingsGateway.Application.ImportPreviewOutputBase})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -2577,6 +2839,16 @@
|
||||
运行日志分页DTO
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.BackendLogPageInput.StartTime">
|
||||
<summary>
|
||||
开始时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.BackendLogPageInput.EndTime">
|
||||
<summary>
|
||||
结束时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.BackendLogPageInput.Source">
|
||||
<summary>
|
||||
日志源
|
||||
@@ -2607,6 +2879,16 @@
|
||||
RPC日志分页DTO
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.RpcLogPageInput.StartTime">
|
||||
<summary>
|
||||
开始时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.RpcLogPageInput.EndTime">
|
||||
<summary>
|
||||
结束时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.RpcLogPageInput.Source">
|
||||
<summary>
|
||||
操作源
|
||||
@@ -3023,6 +3305,9 @@
|
||||
<member name="M:ThingsGateway.Application.UploadDeviceService.PreviewAsync(Microsoft.AspNetCore.Components.Forms.IBrowserFile)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.UploadDeviceService.PreviewAsync(System.IO.MemoryStream)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Application.VariableAddInput">
|
||||
<summary>
|
||||
添加变量DTO
|
||||
@@ -3279,6 +3564,9 @@
|
||||
<member name="M:ThingsGateway.Application.VariableService.PreviewAsync(Microsoft.AspNetCore.Components.Forms.IBrowserFile)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.VariableService.PreviewAsync(System.IO.MemoryStream,System.Collections.Generic.List{ThingsGateway.Application.CollectDevice},System.Collections.Generic.List{ThingsGateway.Application.UploadDevice})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.VariableService.ImportAsync(System.Collections.Generic.Dictionary{System.String,ThingsGateway.Application.ImportPreviewOutputBase})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -3505,7 +3793,7 @@
|
||||
执行特殊方法
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
执行变量写入
|
||||
</summary>
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
using Mapster;
|
||||
@@ -73,7 +74,7 @@ public class AlarmWorker : BackgroundService
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<SqlSugarClient>> GetAlarmDbAsync()
|
||||
{
|
||||
var ConfigService = ServiceHelper.Services.GetService<IConfigService>();
|
||||
var ConfigService = App.GetService<IConfigService>();
|
||||
var alarmEnable = (await ConfigService.GetByConfigKeyAsync(ThingsGatewayConfigConst.ThingGateway_AlarmConfig_Base, ThingsGatewayConfigConst.Config_Alarm_Enable))?.ConfigValue?.ToBoolean();
|
||||
var alarmDbType = (await ConfigService.GetByConfigKeyAsync(ThingsGatewayConfigConst.ThingGateway_AlarmConfig_Base, ThingsGatewayConfigConst.Config_Alarm_DbType))?.ConfigValue;
|
||||
var alarmConnstr = (await ConfigService.GetByConfigKeyAsync(ThingsGatewayConfigConst.ThingGateway_AlarmConfig_Base, ThingsGatewayConfigConst.Config_Alarm_ConnStr))?.ConfigValue;
|
||||
@@ -595,7 +596,7 @@ public class AlarmWorker : BackgroundService
|
||||
var cacheData = await CacheDb.GetCacheData();
|
||||
if (cacheData.Count > 0)
|
||||
{
|
||||
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryAlarm>>()).ToList();
|
||||
var data = cacheData.SelectMany(a => a.CacheStr.FromJsonString<List<HistoryAlarm>>()).ToList();
|
||||
try
|
||||
{
|
||||
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
|
||||
@@ -633,7 +634,7 @@ public class AlarmWorker : BackgroundService
|
||||
var cacheDatas = list.ChunkTrivialBetter(500);
|
||||
foreach (var a in cacheDatas)
|
||||
{
|
||||
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
||||
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.FriendlyException;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
@@ -79,7 +80,7 @@ public class CollectDeviceCore
|
||||
{
|
||||
_pluginService = ServiceHelper.Services.GetService<PluginSingletonService>();
|
||||
GlobalDeviceData = ServiceHelper.Services.GetService<GlobalDeviceData>();
|
||||
DriverPluginService = ServiceHelper.Services.GetService<IDriverPluginService>();
|
||||
DriverPluginService = App.GetService<IDriverPluginService>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -206,6 +207,8 @@ public class CollectDeviceCore
|
||||
{
|
||||
try
|
||||
{
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime);
|
||||
|
||||
if (_device == null)
|
||||
{
|
||||
_logger?.LogError(nameof(CollectDeviceRunTime) + "设备不能为null");
|
||||
@@ -287,6 +290,8 @@ public class CollectDeviceCore
|
||||
{
|
||||
bool isUpDevice = Device != device;
|
||||
_device = device;
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime);
|
||||
|
||||
_logger = ServiceHelper.Services.GetService<ILoggerFactory>().CreateLogger("采集设备:" + _device.Name);
|
||||
//更新插件信息
|
||||
CreatDriver();
|
||||
@@ -330,11 +335,6 @@ public class CollectDeviceCore
|
||||
return ThreadRunReturn.Continue;
|
||||
}
|
||||
|
||||
if (DeviceVariableSourceReads.Count == 0 && Device.DeviceVariableRunTimes.Where(a => string.IsNullOrEmpty(a.OtherMethod)).Any())
|
||||
{
|
||||
//无采集变量
|
||||
return ThreadRunReturn.Continue;
|
||||
}
|
||||
if (token.IsCancellationRequested)
|
||||
return ThreadRunReturn.Break;
|
||||
|
||||
@@ -398,7 +398,7 @@ public class CollectDeviceCore
|
||||
var read = await InvokeMethodAsync(deviceVariableMethodRead, token);
|
||||
if (read.IsSuccess)
|
||||
{
|
||||
_logger?.LogTrace(_device.Name + "执行方法[" + deviceVariableMethodRead.MethodInfo.Name + "] 成功" + read.Content.ToJson());
|
||||
_logger?.LogTrace(_device.Name + "执行方法[" + deviceVariableMethodRead.MethodInfo.Name + "] 成功" + read.Content.ToJsonString());
|
||||
deviceMethodsVariableSuccessNum += 1;
|
||||
}
|
||||
else
|
||||
@@ -438,11 +438,11 @@ public class CollectDeviceCore
|
||||
if (_driver.IsConnected())
|
||||
{
|
||||
//更新设备活动时间
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 0);
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, errorCount: 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 999);
|
||||
Device.SetDeviceStatus(errorCount: 999);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ public class CollectDeviceCore
|
||||
|
||||
if (!string.IsNullOrEmpty(methodResult.MethodStr))
|
||||
{
|
||||
string[] strs = methodResult.MethodStr?.Trim()?.Split(';');
|
||||
string[] strs = methodResult.MethodStr?.Trim()?.TrimEnd(';').Split(';');
|
||||
try
|
||||
{
|
||||
int index = 0;
|
||||
@@ -546,6 +546,8 @@ public class CollectDeviceCore
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strs.Length <= index)
|
||||
continue;
|
||||
//得到对于的方法参数值
|
||||
methodResult.MethodObj[i] = methodResult.Converter.ConvertFrom(strs[index], ps[i].ParameterType);
|
||||
index++;
|
||||
@@ -601,8 +603,8 @@ public class CollectDeviceCore
|
||||
|
||||
if (!string.IsNullOrEmpty(deviceVariableMethodSource.MethodStr) || !string.IsNullOrEmpty(value))
|
||||
{
|
||||
string[] strs1 = deviceVariableMethodSource.MethodStr?.Trim()?.Split(';');
|
||||
string[] strs2 = value?.Trim()?.Split(';');
|
||||
string[] strs1 = deviceVariableMethodSource.MethodStr?.Trim()?.TrimEnd(';').Split(';');
|
||||
string[] strs2 = value?.Trim()?.TrimEnd(';').Split(';');
|
||||
//通过分号分割,并且合并参数
|
||||
var strs = strs1?.SpliceArray(strs2);
|
||||
int index = 0;
|
||||
@@ -668,18 +670,25 @@ public class CollectDeviceCore
|
||||
if (method.HasReturn && result != null && result.IsSuccess)
|
||||
{
|
||||
var content = deviceVariableMethodSource.Converter.ConvertTo(result.Content?.ToString()?.Replace($"\0", ""));
|
||||
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(content);
|
||||
if (!operResult.IsSuccess)
|
||||
if (isRead)
|
||||
{
|
||||
_logger?.LogWarning(operResult.Message, ToString());
|
||||
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(content);
|
||||
if (!operResult.IsSuccess)
|
||||
{
|
||||
_logger?.LogWarning(operResult.Message, ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null);
|
||||
if (!operResult.IsSuccess)
|
||||
if (isRead && !result.IsSuccess)
|
||||
{
|
||||
_logger?.LogWarning(operResult.Message, ToString());
|
||||
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null, isOnline: false);
|
||||
if (!operResult.IsSuccess)
|
||||
{
|
||||
_logger?.LogWarning(operResult.Message, ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -708,46 +717,46 @@ public class CollectDeviceCore
|
||||
/// 执行变量写入
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal async Task<OperResult> InVokeWriteAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
internal async Task<Dictionary<string, OperResult>> InVokeWriteAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
await easyLock.WaitAsync();
|
||||
if (IsShareChannel) _driver.InitDataAdapter();
|
||||
Dictionary<string, OperResult> results = new();
|
||||
foreach (var deviceVariable in writeInfoLists.Keys)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions))
|
||||
{
|
||||
var jToken = writeInfoLists[deviceVariable];
|
||||
object rawdata;
|
||||
if (jToken is JValue jValue)
|
||||
{
|
||||
rawdata = jValue.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawdata = jToken.ToString();
|
||||
}
|
||||
object data;
|
||||
try
|
||||
{
|
||||
data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata);
|
||||
writeInfoLists[deviceVariable] = JToken.FromObject(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
results.Add(deviceVariable.Name, new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions))
|
||||
{
|
||||
var jToken = value;
|
||||
object rawdata;
|
||||
if (jToken is JValue jValue)
|
||||
{
|
||||
rawdata = jValue.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawdata = jToken.ToString();
|
||||
}
|
||||
object data;
|
||||
try
|
||||
{
|
||||
data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata);
|
||||
var result = await _driver.WriteValueAsync(deviceVariable, JToken.FromObject(data), token);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = await _driver.WriteValueAsync(deviceVariable, value, token);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
var result = await _driver.WriteValuesAsync(writeInfoLists.
|
||||
Where(a => !results.Any(b => b.Key == a.Key.Name)).
|
||||
ToDictionary(item => item.Key, item => item.Value),
|
||||
token);
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -755,6 +764,8 @@ public class CollectDeviceCore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行轮询特殊方法,并设置变量值
|
||||
/// </summary>
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.FriendlyException;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
@@ -38,7 +39,7 @@ public class CollectDeviceWorker : BackgroundService
|
||||
ServiceHelper.Services = serviceProvider;
|
||||
_logger = logger;
|
||||
_pluginService = ServiceHelper.Services.GetService<PluginSingletonService>();
|
||||
_collectDeviceService = ServiceHelper.Services.GetService<ICollectDeviceService>();
|
||||
_collectDeviceService = App.GetService<ICollectDeviceService>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 读取未停止的采集设备List
|
||||
@@ -95,10 +96,13 @@ public class CollectDeviceWorker : BackgroundService
|
||||
await RemoveAllDeviceThreadAsync();
|
||||
//创建全部采集线程
|
||||
await CreatAllDeviceThreadsAsync();
|
||||
//开始全部采集线程
|
||||
await StartAllDeviceThreadsAsync();
|
||||
|
||||
//开始其他后台服务
|
||||
await StartOtherHostService();
|
||||
|
||||
//开始全部采集线程
|
||||
await StartAllDeviceThreadsAsync();
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -411,7 +415,7 @@ public class CollectDeviceWorker : BackgroundService
|
||||
/// <returns></returns>
|
||||
public Type GetDebugUI(long driverId)
|
||||
{
|
||||
var driverPluginService = ServiceHelper.Services.GetService<IDriverPluginService>();
|
||||
var driverPluginService = App.GetService<IDriverPluginService>();
|
||||
var driverPlugin = driverPluginService.GetDriverPluginById(driverId);
|
||||
var driver = _pluginService.GetDriver(driverPlugin);
|
||||
driver?.SafeDispose();
|
||||
@@ -425,7 +429,7 @@ public class CollectDeviceWorker : BackgroundService
|
||||
/// <returns></returns>
|
||||
public List<string> GetDeviceMethods(long devId)
|
||||
{
|
||||
var driverPluginService = ServiceHelper.Services.GetService<IDriverPluginService>();
|
||||
var driverPluginService = App.GetService<IDriverPluginService>();
|
||||
var driverId = _collectDeviceService.GetDeviceById(devId).PluginId;
|
||||
var driverPlugin = driverPluginService.GetDriverPluginById(driverId);
|
||||
var driver = (CollectBase)_pluginService.GetDriver(driverPlugin);
|
||||
@@ -442,7 +446,7 @@ public class CollectDeviceWorker : BackgroundService
|
||||
/// <returns></returns>
|
||||
public List<DependencyProperty> GetDevicePropertys(long driverId, long devId = 0)
|
||||
{
|
||||
var driverPluginService = ServiceHelper.Services.GetService<IDriverPluginService>();
|
||||
var driverPluginService = App.GetService<IDriverPluginService>();
|
||||
var driverPlugin = driverPluginService.GetDriverPluginById(driverId);
|
||||
var driver = _pluginService.GetDriver(driverPlugin);
|
||||
var Propertys = _pluginService.GetDriverProperties(driver);
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
using Mapster;
|
||||
@@ -59,7 +60,7 @@ public class HistoryValueWorker : BackgroundService
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<SqlSugarClient>> GetHisDbAsync()
|
||||
{
|
||||
var ConfigService = ServiceHelper.Services.GetService<IConfigService>();
|
||||
var ConfigService = App.GetService<IConfigService>();
|
||||
var hisEnable = (await ConfigService.GetByConfigKeyAsync(ThingsGatewayConfigConst.ThingGateway_HisConfig_Base, ThingsGatewayConfigConst.Config_His_Enable))?.ConfigValue?.ToBoolean();
|
||||
var hisDbType = (await ConfigService.GetByConfigKeyAsync(ThingsGatewayConfigConst.ThingGateway_HisConfig_Base, ThingsGatewayConfigConst.Config_His_DbType))?.ConfigValue;
|
||||
var hisConnstr = (await ConfigService.GetByConfigKeyAsync(ThingsGatewayConfigConst.ThingGateway_HisConfig_Base, ThingsGatewayConfigConst.Config_His_ConnStr))?.ConfigValue;
|
||||
@@ -224,7 +225,7 @@ public class HistoryValueWorker : BackgroundService
|
||||
|
||||
//缓存值
|
||||
var cacheData = await CacheDb.GetCacheData();
|
||||
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryValue>>()).ToList();
|
||||
var data = cacheData.SelectMany(a => a.CacheStr.FromJsonString<List<HistoryValue>>()).ToList();
|
||||
try
|
||||
{
|
||||
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
|
||||
@@ -257,7 +258,7 @@ public class HistoryValueWorker : BackgroundService
|
||||
var cacheDatas = collecthis.ChunkTrivialBetter(500);
|
||||
foreach (var a in cacheDatas)
|
||||
{
|
||||
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
||||
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,7 +285,7 @@ public class HistoryValueWorker : BackgroundService
|
||||
var cacheDatas = changehis.ChunkTrivialBetter(500);
|
||||
foreach (var a in cacheDatas)
|
||||
{
|
||||
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
||||
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -100,7 +101,7 @@ public class MemoryVariableWorker : BackgroundService
|
||||
_logger?.LogInformation($"中间变量计算线程开始");
|
||||
try
|
||||
{
|
||||
var variableService = ServiceHelper.Services.GetService<IVariableService>();
|
||||
var variableService = App.GetService<IVariableService>();
|
||||
var data = await variableService.GetMemoryVariableRuntimeAsync();
|
||||
_globalDeviceData.MemoryVariables = new(data);
|
||||
StatuString = OperResult.CreateSuccessResult();
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.FriendlyException;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
@@ -57,7 +58,7 @@ public class UploadDeviceCore
|
||||
public UploadDeviceCore()
|
||||
{
|
||||
_pluginService = ServiceHelper.Services.GetService<PluginSingletonService>();
|
||||
DriverPluginService = ServiceHelper.Services.GetService<IDriverPluginService>();
|
||||
DriverPluginService = App.GetService<IDriverPluginService>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
using Furion.FriendlyException;
|
||||
using Furion.Logging.Extensions;
|
||||
|
||||
@@ -41,7 +42,7 @@ public class UploadDeviceWorker : BackgroundService
|
||||
_logger = logger;
|
||||
|
||||
_pluginService = ServiceHelper.Services.GetService<PluginSingletonService>();
|
||||
_uploadDeviceService = ServiceHelper.Services.GetService<IUploadDeviceService>();
|
||||
_uploadDeviceService = App.GetService<IUploadDeviceService>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 上传设备List
|
||||
@@ -294,7 +295,7 @@ public class UploadDeviceWorker : BackgroundService
|
||||
/// <returns></returns>
|
||||
public List<DependencyProperty> GetDevicePropertys(long driverId, long devId = 0)
|
||||
{
|
||||
var driverPluginService = ServiceHelper.Services.GetService<IDriverPluginService>();
|
||||
var driverPluginService = App.GetService<IDriverPluginService>();
|
||||
var driverPlugin = driverPluginService.GetDriverPluginById(driverId);
|
||||
|
||||
var driver = _pluginService.GetDriver(driverPlugin);
|
||||
@@ -325,7 +326,7 @@ public class UploadDeviceWorker : BackgroundService
|
||||
/// <returns></returns>
|
||||
public List<DependencyProperty> GetVariablePropertys(long driverId, List<DependencyProperty> dependencyProperties = null)
|
||||
{
|
||||
var driverPluginService = ServiceHelper.Services.GetService<IDriverPluginService>();
|
||||
var driverPluginService = App.GetService<IDriverPluginService>();
|
||||
var driverPlugin = driverPluginService.GetDriverPluginById(driverId);
|
||||
var driver = (UpLoadBase)_pluginService.GetDriver(driverPlugin);
|
||||
var Propertys = _pluginService.GetDriverVariableProperties(driver);
|
||||
|
@@ -75,30 +75,33 @@
|
||||
(item.Value.HasError ? "出现错误" : "验证成功")
|
||||
)
|
||||
</MSubheader>
|
||||
|
||||
<MVirtualScroll Context="item1" Height=300 OverscanCount=2 ItemSize="60" Items="item.Value.Results">
|
||||
<ItemContent>
|
||||
<MListItem>
|
||||
<MListItemAction>
|
||||
<MChip Class="ma-2">
|
||||
@(
|
||||
if (item.Value.HasError)
|
||||
{
|
||||
<MVirtualScroll Context="item1" Height=300 OverscanCount=2 ItemSize="60" Items="item.Value.Results.Where(a=>!a.isSuccess).ToList()">
|
||||
<ItemContent>
|
||||
<MListItem>
|
||||
<MListItemAction>
|
||||
<MChip Class="ma-2">
|
||||
@(
|
||||
$"第{item1.row}行"
|
||||
)
|
||||
</MChip>
|
||||
</MListItemAction>
|
||||
</MChip>
|
||||
</MListItemAction>
|
||||
|
||||
<MListItemContent>
|
||||
<MListItemTitle Class=@((item1.isSuccess?"green--text":"red--text"))>
|
||||
<strong>@item1.resultString</strong>
|
||||
</MListItemTitle>
|
||||
</MListItemContent>
|
||||
<MListItemContent>
|
||||
<MListItemTitle Class=@((item1.isSuccess?"green--text":"red--text"))>
|
||||
<strong>@item1.resultString</strong>
|
||||
</MListItemTitle>
|
||||
</MListItemContent>
|
||||
|
||||
</MListItem>
|
||||
</MListItem>
|
||||
|
||||
<MDivider></MDivider>
|
||||
<MDivider></MDivider>
|
||||
|
||||
</ItemContent>
|
||||
</MVirtualScroll>
|
||||
</ItemContent>
|
||||
</MVirtualScroll>
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user