mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-23 11:51:09 +08:00
Compare commits
64 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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 | ||
![]() |
877445bc0a | ||
![]() |
9a5b345bde | ||
![]() |
fc9e8ea7b3 | ||
![]() |
32be6fcfc1 | ||
![]() |
49847236c2 | ||
![]() |
d8424443e6 | ||
![]() |
f3b571ec3f | ||
![]() |
99318bb5d7 | ||
![]() |
1aa154c9aa | ||
![]() |
c65d8a445b | ||
![]() |
80f4f85570 | ||
![]() |
5beee43a6b | ||
![]() |
8d6ae203a0 | ||
![]() |
4353479a5c | ||
![]() |
34d7687f9e | ||
![]() |
b1dc3cf4af | ||
![]() |
6a58b95933 | ||
![]() |
d3badfd02b | ||
![]() |
0098be057b | ||
![]() |
6f972aa515 | ||
![]() |
7407ba6313 | ||
![]() |
1c79de207b | ||
![]() |
257c79db92 | ||
![]() |
9d1934a308 | ||
![]() |
d70f959902 | ||
![]() |
e4d810222f | ||
![]() |
bc1af4ae07 | ||
![]() |
6e688ef43f | ||
![]() |
f0fe1b23dc | ||
![]() |
aaf2006401 | ||
![]() |
b821e26935 | ||
![]() |
7ae4287157 | ||
![]() |
c6fcc38a65 | ||
![]() |
ab2d5c8853 | ||
![]() |
5e557ff0bc | ||
![]() |
918ca449a1 | ||
![]() |
8e73368008 |
@@ -5,12 +5,11 @@
|
||||
|
||||
**NetCore** 跨平台边缘采集网关(工业设备采集)
|
||||
|
||||
**ThingsGateway** 存储库同时提供 [**设备采集驱动**](https://www.nuget.org/profiles/KimDiego)
|
||||
**ThingsGateway** 存储库同时提供 [**设备采集驱动**](https://www.nuget.org/packages?q=Tags%3A%22ThingsGateway%22)
|
||||
|
||||
**ThingsGateway** 存储库同时提供 **基于Blazor的权限框架** 查看 [**ThingsGateway.Admin**](https://gitee.com/dotnetchina/ThingsGateway/blob/master/framework/ThingsGateway.Admin.sln)
|
||||
|
||||
|
||||
|
||||
## 文档
|
||||
|
||||
[ThingsGateway](https://diego2098.gitee.io/thingsgateway-docs/) 文档。
|
||||
@@ -23,7 +22,9 @@
|
||||
|
||||
[ThingsGateway演示地址](http://120.24.62.140:5000/)
|
||||
|
||||
账户 : **superAdmin** 密码 : **111111**
|
||||
账户 : **superAdmin**
|
||||
|
||||
密码 : **111111**
|
||||
|
||||
## 赞助
|
||||
|
||||
|
@@ -81,6 +81,15 @@ dotnet_diagnostic.CA2208.severity = none
|
||||
# IDE0057: 使用范围运算符
|
||||
dotnet_diagnostic.IDE0057.severity = none
|
||||
|
||||
# IDE0056: 使用索引运算符
|
||||
dotnet_diagnostic.IDE0056.severity = none
|
||||
|
||||
# CA1830: 最好使用 StringBuilder 的强类型 Append 和 Insert 方法重载
|
||||
dotnet_diagnostic.CA1830.severity = none
|
||||
|
||||
# CA1847: 将字符型文本用于单个字符查找
|
||||
dotnet_diagnostic.CA1847.severity = none
|
||||
|
||||
[*.vb]
|
||||
#### 命名样式 ####
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Version>2.0.3.0</Version>
|
||||
<Version>2.1.0.0</Version>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
|
@@ -19,7 +19,7 @@ using ThingsGateway.Admin.Core;
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
/// <summary>
|
||||
/// 后台登录控制器
|
||||
/// 文件下载
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(CateGoryConst.ThingsGatewayAdmin, Order = 200)]
|
||||
[Route("file")]
|
||||
|
@@ -30,7 +30,7 @@
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Admin.Application.FileController">
|
||||
<summary>
|
||||
后台登录控制器
|
||||
文件下载
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Admin.Application.FileController.#ctor(ThingsGateway.Admin.Application.IFileService,ThingsGateway.Admin.Application.IOperateLogService,ThingsGateway.Admin.Application.IVisitLogService)">
|
||||
|
@@ -52,8 +52,8 @@ public class OpenApiSessionService : DbRepository<OpenApiUser>, IOpenApiSessionS
|
||||
//获取该用户的verificat信息
|
||||
List<VerificatInfo> verificatInfos = await _verificatService.GetOpenApiVerificatIdAsync(input.Id);
|
||||
//当前需要踢掉用户的verificat
|
||||
var deleteVerificats = verificatInfos.Where(it => input.VerificatIds.Contains(it.Id)).ToList();
|
||||
await _verificatService.SetOpenApiVerificatIdAsync(input.Id, deleteVerificats);//如果还有verificat则更新verificat
|
||||
var setVerificats = verificatInfos.Where(it => !input.VerificatIds.Contains(it.Id)).ToList();
|
||||
await _verificatService.SetOpenApiVerificatIdAsync(input.Id, setVerificats);//如果还有verificat则更新verificat
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -52,12 +52,11 @@ public class SessionService : DbRepository<SysUser>, ISessionService
|
||||
{
|
||||
//获取该用户的verificat信息
|
||||
List<VerificatInfo> verificatInfos = await _verificatService.GetVerificatIdAsync(input.Id);
|
||||
//当前需要踢掉用户的verificat
|
||||
List<VerificatInfo> deleteVerificats = new();
|
||||
|
||||
//踢掉包含verificat列表的verificat信息
|
||||
deleteVerificats = verificatInfos.Where(it => input.VerificatIds.Contains(it.Id)).ToList();
|
||||
await _verificatService.SetVerificatIdAsync(input.Id, deleteVerificats);//如果还有verificat则更新verificat
|
||||
var setVerificats = verificatInfos.Where(it => !input.VerificatIds.Contains(it.Id)).ToList();
|
||||
var deleteVerificats = verificatInfos.Where(it => input.VerificatIds.Contains(it.Id)).ToList();
|
||||
await _verificatService.SetVerificatIdAsync(input.Id, setVerificats);//如果还有verificat则更新verificat
|
||||
|
||||
var message = "您已被强制下线!";
|
||||
await _noticeService.LogoutAsync(input.Id, deleteVerificats, message);//通知下线
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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
|
||||
|
||||
@@ -22,17 +22,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; }
|
||||
|
@@ -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
|
||||
|
||||
@@ -49,11 +49,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,8 +14,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="Masa.Blazor" Version="1.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.9" />
|
||||
<PackageReference Include="Masa.Blazor" Version="1.0.2" />
|
||||
<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>
|
||||
|
@@ -153,7 +153,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)
|
||||
|
@@ -48,8 +48,7 @@
|
||||
var controllerTypes = App.EffectiveTypes.
|
||||
Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
|
||||
&& u.IsDefined(typeof(Microsoft.AspNetCore.Components.RouteAttribute), false))
|
||||
.Where(it => it.Assembly != typeof(BlazorApp).Assembly)
|
||||
;
|
||||
.Where(it => it.Assembly != typeof(BlazorApp).Assembly);
|
||||
var assemblys = controllerTypes?.Select(it => it.Assembly)?.Distinct();
|
||||
return assemblys;
|
||||
}
|
||||
|
@@ -189,7 +189,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ItemColWithDTTemplate!=null)
|
||||
if (ItemColWithDTTemplate != null)
|
||||
{
|
||||
@ItemColWithDTTemplate(context)
|
||||
}
|
||||
@@ -220,7 +220,7 @@
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
</ItemColContent>
|
||||
@@ -310,16 +310,24 @@
|
||||
{
|
||||
string value = DetailModelPairs[item.Value];
|
||||
{
|
||||
<tr @key="item.Text">
|
||||
<td class="text-start table-minwidth">
|
||||
@item.Text
|
||||
</td>
|
||||
<td class="text-start ">
|
||||
<div style="word-break:break-all; white-space:pre-wrap;">
|
||||
@value
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@if (Detailemplate != null)
|
||||
{
|
||||
@Detailemplate((item,value))
|
||||
}
|
||||
else
|
||||
{
|
||||
<tr @key="item.Text">
|
||||
<td class="text-start table-minwidth">
|
||||
@item.Text
|
||||
</td>
|
||||
<td class="text-start ">
|
||||
<div style="word-break:break-all; white-space:pre-wrap;">
|
||||
@value
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -72,12 +72,6 @@ public partial class AppDataTable<TItem, SearchItem, AddItem, EditItem> : IAppDa
|
||||
[Parameter]
|
||||
public bool Dense { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 明细行模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment<TItem> DetailRowTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编辑项委托
|
||||
/// </summary>
|
||||
@@ -89,6 +83,11 @@ public partial class AppDataTable<TItem, SearchItem, AddItem, EditItem> : IAppDa
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment<EditItem> EditTemplate { get; set; }
|
||||
/// <summary>
|
||||
/// 获得/设置 详情模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment<(DataTableHeader<TItem>, string)> Detailemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表头过滤,返回DataTableHeader列表,传输参数已包含全部初始表头与表头标题
|
||||
|
@@ -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
|
||||
|
||||
@@ -18,7 +18,7 @@ using ThingsGateway.Admin.Core;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor;
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ҳ
|
||||
/// 首页
|
||||
/// </summary>
|
||||
public partial class Index
|
||||
{
|
||||
|
@@ -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
|
||||
{
|
||||
@@ -50,25 +50,25 @@ public partial class UserCenter
|
||||
{
|
||||
await 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 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 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);
|
||||
}
|
||||
@@ -78,6 +78,6 @@ public partial class UserCenter
|
||||
{
|
||||
await UserCenterService.UpdateUserInfoAsync(_updateInfoInput);
|
||||
await MainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
}
|
@@ -43,11 +43,6 @@
|
||||
表格紧凑
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Admin.Blazor.Core.AppDataTable`4.DetailRowTemplate">
|
||||
<summary>
|
||||
获得/设置 明细行模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Admin.Blazor.Core.AppDataTable`4.EditCallAsync">
|
||||
<summary>
|
||||
编辑项委托
|
||||
@@ -58,6 +53,11 @@
|
||||
获得/设置 编辑模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Admin.Blazor.Core.AppDataTable`4.Detailemplate">
|
||||
<summary>
|
||||
获得/设置 详情模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Admin.Blazor.Core.AppDataTable`4.FilterHeaders">
|
||||
<summary>
|
||||
表头过滤,返回DataTableHeader列表,传输参数已包含全部初始表头与表头标题
|
||||
|
@@ -9,13 +9,13 @@
|
||||
</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.94" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.41" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.41" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.8.8.41" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.102" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
<PackageReference Include="MiniExcel" Version="1.31.0" />
|
||||
<PackageReference Include="MiniExcel" Version="1.31.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -21,7 +21,7 @@ using ThingsGateway.Application;
|
||||
namespace ThingsGateway.ApiController;
|
||||
|
||||
/// <summary>
|
||||
/// 后台登录控制器
|
||||
/// 文件下载
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(CateGoryConst.ThingsGatewayAdmin, Order = 200)]
|
||||
[Route("gatewayFile")]
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,7 @@
|
||||
</member>
|
||||
<member name="T:ThingsGateway.ApiController.FileController">
|
||||
<summary>
|
||||
后台登录控制器
|
||||
文件下载
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.ApiController.FileController.#ctor(ThingsGateway.Application.IRpcLogService,ThingsGateway.Application.IBackendLogService,ThingsGateway.Application.ICollectDeviceService,ThingsGateway.Application.IUploadDeviceService,ThingsGateway.Application.IVariableService)">
|
||||
|
@@ -31,7 +31,7 @@ public class DeviceVariable : MemoryVariable
|
||||
public virtual long DeviceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入表达式
|
||||
/// 单位
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Unit", ColumnDescription = "单位", Length = 200, IsNullable = true)]
|
||||
[DataTable(Order = 3, IsShow = true, Sortable = true)]
|
||||
@@ -59,12 +59,7 @@ public class DeviceVariable : MemoryVariable
|
||||
[DataTable(Order = 3, IsShow = true, Sortable = true)]
|
||||
public string VariableAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入表达式
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "WriteExpressions", ColumnDescription = "写入表达式", Length = 200, IsNullable = true)]
|
||||
[DataTable(Order = 7, IsShow = true, Sortable = true)]
|
||||
public string WriteExpressions { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否中间变量
|
||||
|
@@ -51,7 +51,12 @@ public class MemoryVariable : BaseEntity
|
||||
[SugarColumn(ColumnName = "ReadExpressions", ColumnDescription = "读取表达式", Length = 200, IsNullable = true)]
|
||||
[DataTable(Order = 7, IsShow = true, Sortable = true, CellClass = " table-text-truncate ")]
|
||||
public string ReadExpressions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入表达式
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "WriteExpressions", ColumnDescription = "写入表达式", Length = 200, IsNullable = true)]
|
||||
[DataTable(Order = 7, IsShow = true, Sortable = true)]
|
||||
public string WriteExpressions { get; set; }
|
||||
/// <summary>
|
||||
/// 是否中间变量
|
||||
/// </summary>
|
||||
|
@@ -20,6 +20,8 @@ public class VariableData
|
||||
public long Id { get; set; }
|
||||
/// <inheritdoc cref="MemoryVariable.Name"/>
|
||||
public string Name { get; set; }
|
||||
/// <inheritdoc cref="DeviceVariable.Unit"/>
|
||||
public string Unit { get; set; }
|
||||
/// <inheritdoc cref="MemoryVariable.Description"/>
|
||||
public string Description { get; set; }
|
||||
/// <inheritdoc cref="DeviceVariableRunTime.DeviceName"/>
|
||||
@@ -36,7 +38,7 @@ public class VariableData
|
||||
public bool IsOnline { get; set; }
|
||||
/// <inheritdoc cref="MemoryVariable.ReadExpressions"/>
|
||||
public string ReadExpressions { get; set; }
|
||||
/// <inheritdoc cref="DeviceVariable.WriteExpressions"/>
|
||||
/// <inheritdoc cref="MemoryVariable.WriteExpressions"/>
|
||||
public string WriteExpressions { get; set; }
|
||||
/// <inheritdoc cref="DeviceVariable.IntervalTime"/>
|
||||
public int IntervalTime { get; set; }
|
||||
|
@@ -17,8 +17,6 @@ using Newtonsoft.Json.Linq;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
namespace ThingsGateway.Application;
|
||||
/// <summary>
|
||||
/// <para></para>
|
||||
@@ -38,6 +36,10 @@ public abstract class CollectBase : DriverBase
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool IsSupportRequest { get; }
|
||||
/// <summary>
|
||||
/// 一般底层驱动,也有可能为null
|
||||
/// </summary>
|
||||
protected abstract IReadWriteDevice PLC { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据转换器
|
||||
@@ -179,10 +181,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>
|
||||
/// 初始化
|
||||
|
@@ -48,92 +48,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()
|
||||
{
|
||||
|
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
@@ -55,7 +55,7 @@ public interface IVariableService : ITransient
|
||||
/// <summary>
|
||||
/// 导出
|
||||
/// </summary>
|
||||
Task<MemoryStream> ExportFileAsync(List<DeviceVariable> collectDeviceVariables = null);
|
||||
Task<MemoryStream> ExportFileAsync(List<DeviceVariable> collectDeviceVariables = null, string deviceName = null);
|
||||
/// <summary>
|
||||
/// 导出
|
||||
/// </summary>
|
||||
|
@@ -318,7 +318,7 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
|
||||
/// <inheritdoc/>
|
||||
[OperDesc("导出采集变量表", IsRecordPar = false)]
|
||||
public async Task<MemoryStream> ExportFileAsync(List<DeviceVariable> deviceVariables = null)
|
||||
public async Task<MemoryStream> ExportFileAsync(List<DeviceVariable> deviceVariables = null, string deviceName = null)
|
||||
{
|
||||
deviceVariables ??= await GetListAsync(a => !a.IsMemoryVariable);
|
||||
|
||||
@@ -343,7 +343,8 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
);
|
||||
Dictionary<string, object> variableExport = new();
|
||||
//变量实体没有包含设备名称,手动插入
|
||||
variableExport.Add(ExportHelpers.DeviceName, collectDeviceDicts[devData.DeviceId].Name);
|
||||
var devName = collectDeviceDicts.GetValueOrDefault(devData.DeviceId)?.Name ?? deviceName;
|
||||
variableExport.Add(ExportHelpers.DeviceName, devName);
|
||||
|
||||
foreach (var item in data)
|
||||
{
|
||||
@@ -445,7 +446,7 @@ public class VariableService : DbRepository<DeviceVariable>, IVariableService
|
||||
try
|
||||
{
|
||||
var variable = ((ExpandoObject)item).ConvertToEntity<DeviceVariable>(true);
|
||||
|
||||
variable.IsMemoryVariable = true;
|
||||
//变量ID都需要手动补录
|
||||
variables.Add(variable);
|
||||
if (dbVariableDicts.TryGetValue(variable.Name, out var dbvar1))
|
||||
|
@@ -37,7 +37,7 @@
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -360,7 +360,7 @@
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.DeviceVariable.Unit">
|
||||
<summary>
|
||||
写入表达式
|
||||
单位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.DeviceVariable.IntervalTime">
|
||||
@@ -378,11 +378,6 @@
|
||||
变量地址,可能带有额外的信息,比如<see cref="T:ThingsGateway.Foundation.DataFormat"/> ,以;分割
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.DeviceVariable.WriteExpressions">
|
||||
<summary>
|
||||
写入表达式
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.DeviceVariable.IsMemoryVariable">
|
||||
<summary>
|
||||
是否中间变量
|
||||
@@ -524,6 +519,11 @@
|
||||
读取表达式
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MemoryVariable.WriteExpressions">
|
||||
<summary>
|
||||
写入表达式
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.MemoryVariable.IsMemoryVariable">
|
||||
<summary>
|
||||
是否中间变量
|
||||
@@ -1791,6 +1791,9 @@
|
||||
<member name="P:ThingsGateway.Application.VariableData.Name">
|
||||
<inheritdoc cref="P:ThingsGateway.Application.MemoryVariable.Name"/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.VariableData.Unit">
|
||||
<inheritdoc cref="P:ThingsGateway.Application.DeviceVariable.Unit"/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.VariableData.Description">
|
||||
<inheritdoc cref="P:ThingsGateway.Application.MemoryVariable.Description"/>
|
||||
</member>
|
||||
@@ -1816,7 +1819,7 @@
|
||||
<inheritdoc cref="P:ThingsGateway.Application.MemoryVariable.ReadExpressions"/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.VariableData.WriteExpressions">
|
||||
<inheritdoc cref="P:ThingsGateway.Application.DeviceVariable.WriteExpressions"/>
|
||||
<inheritdoc cref="P:ThingsGateway.Application.MemoryVariable.WriteExpressions"/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.VariableData.IntervalTime">
|
||||
<inheritdoc cref="P:ThingsGateway.Application.DeviceVariable.IntervalTime"/>
|
||||
@@ -1852,6 +1855,11 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.CollectBase.PLC">
|
||||
<summary>
|
||||
一般底层驱动,也有可能为null
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.CollectBase.ThingsGatewayBitConverter">
|
||||
<summary>
|
||||
数据转换器
|
||||
@@ -1903,9 +1911,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>
|
||||
@@ -2239,12 +2247,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>
|
||||
@@ -3172,7 +3180,7 @@
|
||||
编辑变量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.IVariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
|
||||
<member name="M:ThingsGateway.Application.IVariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable},System.String)">
|
||||
<summary>
|
||||
导出
|
||||
</summary>
|
||||
@@ -3267,7 +3275,7 @@
|
||||
<member name="M:ThingsGateway.Application.VariableService.MemoryVariableExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.MemoryVariable})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.VariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
|
||||
<member name="M:ThingsGateway.Application.VariableService.ExportFileAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable},System.String)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.VariableService.MemoryVariablePreviewAsync(Microsoft.AspNetCore.Components.Forms.IBrowserFile)">
|
||||
@@ -3502,7 +3510,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>
|
||||
@@ -3561,6 +3569,11 @@
|
||||
开始采集
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceThread.BeforeStopThreadAsync">
|
||||
<summary>
|
||||
停止采集前,提前取消Token
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceThread.StopThreadAsync">
|
||||
<summary>
|
||||
停止采集
|
||||
@@ -3934,6 +3947,11 @@
|
||||
开始上传
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.UploadDeviceThread.BeforeStopThreadAsync">
|
||||
<summary>
|
||||
停止采集前,提前取消Token
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.UploadDeviceThread.StopThreadAsync">
|
||||
<summary>
|
||||
停止上传
|
||||
|
@@ -66,7 +66,7 @@ public class AlarmWorker : BackgroundService
|
||||
/// </summary>
|
||||
public OperResult StatuString { get; set; } = new OperResult("初始化");
|
||||
private ConcurrentQueue<DeviceVariableRunTime> DeviceVariables { get; set; } = new();
|
||||
private ConcurrentQueue<DeviceVariableRunTime> HisAlarmDeviceVariables { get; set; } = new();
|
||||
private ConcurrentQueue<HistoryAlarm> HisAlarmDeviceVariables { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 获取数据库链接
|
||||
/// </summary>
|
||||
@@ -465,7 +465,7 @@ public class AlarmWorker : BackgroundService
|
||||
OnAlarmChanged?.Invoke(item.Adapt<DeviceVariableRunTime>());
|
||||
if (!IsExited)
|
||||
{
|
||||
HisAlarmDeviceVariables.Enqueue(item);
|
||||
HisAlarmDeviceVariables.Enqueue(item.Adapt<HistoryAlarm>());
|
||||
}
|
||||
|
||||
if (eventEnum == EventEnum.Alarm)
|
||||
@@ -536,6 +536,7 @@ public class AlarmWorker : BackgroundService
|
||||
HisAlarmTask = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
_logger?.LogInformation($"历史报警线程开始");
|
||||
await Task.Yield();//返回线程控制,不再阻塞
|
||||
try
|
||||
{
|
||||
await Task.Delay(500, stoppingToken.Token);
|
||||
@@ -561,8 +562,14 @@ public class AlarmWorker : BackgroundService
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (stoppingToken.Token.IsCancellationRequested)
|
||||
{
|
||||
IsExited = true;
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
_logger.LogWarning("连接历史报警表失败,尝试初始化表");
|
||||
sqlSugarClient.CodeFirst.InitTables(typeof(HistoryAlarm));
|
||||
isSuccess = true;
|
||||
StatuString = OperResult.CreateSuccessResult();
|
||||
@@ -586,18 +593,20 @@ public class AlarmWorker : BackgroundService
|
||||
|
||||
//缓存值
|
||||
var cacheData = await CacheDb.GetCacheData();
|
||||
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryAlarm>>()).ToList();
|
||||
try
|
||||
if (cacheData.Count > 0)
|
||||
{
|
||||
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
|
||||
await CacheDb.DeleteCacheData(cacheData.Select(a => a.Id).ToArray());
|
||||
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryAlarm>>()).ToList();
|
||||
try
|
||||
{
|
||||
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
|
||||
await CacheDb.DeleteCacheData(cacheData.Select(a => a.Id).ToArray());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (isSuccess)
|
||||
_logger.LogWarning(ex, "写入历史报警失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (isSuccess)
|
||||
_logger.LogWarning(ex, "写入历史报警失败");
|
||||
}
|
||||
|
||||
if (stoppingToken.Token.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
@@ -605,16 +614,15 @@ public class AlarmWorker : BackgroundService
|
||||
var list = HisAlarmDeviceVariables.ToListWithDequeue();
|
||||
if (list.Count != 0)
|
||||
{
|
||||
var hisalarm = list.Adapt<List<HistoryAlarm>>();
|
||||
////Sql保存
|
||||
hisalarm.ForEach(it =>
|
||||
list.ForEach(it =>
|
||||
{
|
||||
it.Id = YitIdHelper.NextId();
|
||||
});
|
||||
//插入
|
||||
try
|
||||
{
|
||||
await sqlSugarClient.Insertable(hisalarm).ExecuteCommandAsync(stoppingToken.Token);
|
||||
await sqlSugarClient.Insertable(list).ExecuteCommandAsync(stoppingToken.Token);
|
||||
isSuccess = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -622,7 +630,7 @@ public class AlarmWorker : BackgroundService
|
||||
if (isSuccess)
|
||||
_logger.LogWarning(ex, "写入历史报警失败");
|
||||
|
||||
var cacheDatas = hisalarm.ChunkTrivialBetter(500);
|
||||
var cacheDatas = list.ChunkTrivialBetter(500);
|
||||
foreach (var a in cacheDatas)
|
||||
{
|
||||
await CacheDb.AddCacheData("", a.ToJson(), 50000);
|
||||
|
@@ -269,6 +269,7 @@ public class CollectDeviceCore
|
||||
{
|
||||
isInitSuccess = false;
|
||||
GlobalDeviceData.CollectDevices.RemoveWhere(it => it.Id == Device.Id);
|
||||
easyLock.SafeDispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,11 +330,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;
|
||||
|
||||
@@ -437,11 +433,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,7 +529,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;
|
||||
@@ -545,6 +541,8 @@ public class CollectDeviceCore
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strs.Length <= index)
|
||||
continue;
|
||||
//得到对于的方法参数值
|
||||
methodResult.MethodObj[i] = methodResult.Converter.ConvertFrom(strs[index], ps[i].ParameterType);
|
||||
index++;
|
||||
@@ -600,8 +598,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;
|
||||
@@ -667,18 +665,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)
|
||||
{
|
||||
_logger?.LogWarning(operResult.Message, ToString());
|
||||
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null);
|
||||
if (!operResult.IsSuccess)
|
||||
{
|
||||
_logger?.LogWarning(operResult.Message, ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -707,46 +712,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
|
||||
{
|
||||
@@ -754,6 +759,8 @@ public class CollectDeviceCore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行轮询特殊方法,并设置变量值
|
||||
/// </summary>
|
||||
|
@@ -62,6 +62,7 @@ public class CollectDeviceThread : IAsyncDisposable
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await StopThreadAsync();
|
||||
easyLock.SafeDispose();
|
||||
CollectDeviceCores.Clear();
|
||||
}
|
||||
|
||||
@@ -85,6 +86,29 @@ public class CollectDeviceThread : IAsyncDisposable
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 停止采集前,提前取消Token
|
||||
/// </summary>
|
||||
public virtual async Task BeforeStopThreadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
await easyLock.WaitAsync();
|
||||
|
||||
if (DeviceTask == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var token in StoppingTokens)
|
||||
{
|
||||
token.Cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止采集
|
||||
@@ -173,7 +197,10 @@ public class CollectDeviceThread : IAsyncDisposable
|
||||
foreach (var device in CollectDeviceCores)
|
||||
{
|
||||
try
|
||||
{//初始化成功才能执行
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
//初始化成功才能执行
|
||||
if (device.IsInitSuccess)
|
||||
{
|
||||
//如果是共享通道类型,需要每次转换时切换适配器
|
||||
|
@@ -328,6 +328,18 @@ public class CollectDeviceWorker : BackgroundService
|
||||
/// </summary>
|
||||
private async Task RemoveAllDeviceThreadAsync()
|
||||
{
|
||||
await CollectDeviceThreads.ParallelForEachAsync(async (deviceThread, token) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await deviceThread.BeforeStopThreadAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, deviceThread.ToString());
|
||||
}
|
||||
}, 10);
|
||||
|
||||
await CollectDeviceThreads.ParallelForEachAsync(async (deviceThread, token) =>
|
||||
{
|
||||
try
|
||||
|
@@ -167,7 +167,7 @@ public class HistoryValueWorker : BackgroundService
|
||||
HistoryValueTask = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
_logger?.LogInformation($"历史数据线程开始");
|
||||
IsExited = false;
|
||||
await Task.Yield();//返回线程控制,不再阻塞
|
||||
try
|
||||
{
|
||||
var result = await GetHisDbAsync();
|
||||
@@ -191,8 +191,14 @@ public class HistoryValueWorker : BackgroundService
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (stoppingToken.Token.IsCancellationRequested)
|
||||
{
|
||||
IsExited = true;
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
_logger.LogWarning("连接历史数据表失败,尝试初始化表");
|
||||
sqlSugarClient.CodeFirst.InitTables(typeof(HistoryValue));
|
||||
LastIsSuccess = true;
|
||||
StatuString = OperResult.CreateSuccessResult();
|
||||
@@ -204,6 +210,7 @@ public class HistoryValueWorker : BackgroundService
|
||||
_logger.LogWarning(ex, "连接历史数据库失败");
|
||||
}
|
||||
}
|
||||
IsExited = false;
|
||||
|
||||
while (!stoppingToken.Token.IsCancellationRequested)
|
||||
{
|
||||
@@ -299,7 +306,6 @@ public class HistoryValueWorker : BackgroundService
|
||||
LastIsSuccess = false;
|
||||
}
|
||||
}
|
||||
IsExited = true;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -317,9 +323,11 @@ public class HistoryValueWorker : BackgroundService
|
||||
IsExited = true;
|
||||
_logger?.LogError(ex, $"历史数据循环异常");
|
||||
}
|
||||
IsExited = true;
|
||||
}
|
||||
, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重启
|
||||
/// </summary>
|
||||
|
@@ -225,7 +225,13 @@ public class UploadDeviceCore
|
||||
{
|
||||
_logger?.LogError(ex, $"{Device.Name} 释放失败");
|
||||
}
|
||||
isInitSuccess = false;
|
||||
finally
|
||||
{
|
||||
isInitSuccess = false;
|
||||
easyLock.SafeDispose();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -51,6 +51,7 @@ public class UploadDeviceThread : IAsyncDisposable
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await StopThreadAsync();
|
||||
easyLock.SafeDispose();
|
||||
UploadDeviceCores.Clear();
|
||||
}
|
||||
|
||||
@@ -74,6 +75,29 @@ public class UploadDeviceThread : IAsyncDisposable
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 停止采集前,提前取消Token
|
||||
/// </summary>
|
||||
public virtual async Task BeforeStopThreadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
await easyLock.WaitAsync();
|
||||
|
||||
if (DeviceTask == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var token in StoppingTokens)
|
||||
{
|
||||
token.Cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
easyLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止上传
|
||||
@@ -152,7 +176,10 @@ public class UploadDeviceThread : IAsyncDisposable
|
||||
foreach (var device in UploadDeviceCores)
|
||||
{
|
||||
try
|
||||
{//初始化成功才能执行
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
//初始化成功才能执行
|
||||
if (device.IsInitSuccess)
|
||||
{
|
||||
|
||||
|
@@ -239,6 +239,17 @@ public class UploadDeviceWorker : BackgroundService
|
||||
/// </summary>
|
||||
private async Task RemoveAllDeviceThreadAsync()
|
||||
{
|
||||
await UploadDeviceThreads.ParallelForEachAsync(async (deviceThread, token) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await deviceThread.BeforeStopThreadAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, deviceThread.ToString());
|
||||
}
|
||||
}, 10);
|
||||
await UploadDeviceThreads.ParallelForEachAsync(async (deviceThread, token) =>
|
||||
{
|
||||
try
|
||||
|
@@ -102,44 +102,6 @@
|
||||
|
||||
}
|
||||
|
||||
@foreach (var item in ImportPreviews)
|
||||
{
|
||||
<MSubheader Class="mt-2 font-weight-black">
|
||||
@(
|
||||
$"{item.Key},预计导入{item.Value.DataCount}条数据"
|
||||
)
|
||||
</MSubheader>
|
||||
<MSubheader Class=@((item.Value.HasError?"mt-2 red--text":"mt-2 green--text"))>
|
||||
@(
|
||||
(item.Value.HasError ? "出现错误" : "验证成功")
|
||||
)
|
||||
</MSubheader>
|
||||
|
||||
<MVirtualScroll Context="item1" Height=300 OverscanCount=2 ItemSize="60" Items="item.Value.Results">
|
||||
<ItemContent>
|
||||
<MListItem>
|
||||
<MListItemAction>
|
||||
<MChip Class="ma-2">
|
||||
@(
|
||||
$"第{item1.row}行"
|
||||
)
|
||||
</MChip>
|
||||
</MListItemAction>
|
||||
|
||||
<MListItemContent>
|
||||
<MListItemTitle Class=@((item1.isSuccess?"green--text":"red--text"))>
|
||||
<strong>@item1.resultString</strong>
|
||||
</MListItemTitle>
|
||||
</MListItemContent>
|
||||
|
||||
</MListItem>
|
||||
|
||||
<MDivider></MDivider>
|
||||
|
||||
</ItemContent>
|
||||
</MVirtualScroll>
|
||||
|
||||
}
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<MButton Color="primary" Disabled=@ImportPreviews.Any(it=>it.Value.HasError) OnClick="()=>Step=3">下一步</MButton>
|
||||
|
@@ -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
|
||||
|
||||
@@ -21,7 +21,7 @@ using ThingsGateway.Application;
|
||||
|
||||
namespace ThingsGateway.Blazor;
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>excel
|
||||
/// 导入excel
|
||||
/// </summary>
|
||||
public partial class ImportExcel
|
||||
{
|
||||
@@ -33,21 +33,21 @@ public partial class ImportExcel
|
||||
|
||||
bool isSaveImport;
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 导入
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<Dictionary<string, ImportPreviewOutputBase>, Task> Import { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>ʾ
|
||||
/// 是否显示
|
||||
/// </summary>
|
||||
public bool IsShowImport { get; set; }
|
||||
/// <summary>
|
||||
/// Ԥ<EFBFBD><EFBFBD>
|
||||
/// 预览
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<IBrowserFile, Task<Dictionary<string, ImportPreviewOutputBase>>> Preview { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 当前步数
|
||||
/// </summary>
|
||||
public int Step { get; set; }
|
||||
|
||||
@@ -75,7 +75,7 @@ public partial class ImportExcel
|
||||
StateHasChanged();
|
||||
await Import.Invoke(ImportPreviews);
|
||||
_importFile = null;
|
||||
await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
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
|
||||
|
||||
@@ -54,7 +54,7 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
|
||||
/// </summary>
|
||||
public UdpSessionPage UdpSessionPage;
|
||||
/// <summary>
|
||||
/// ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>1-TCPCLIENT<EFBFBD><EFBFBD>2-<2D><><EFBFBD>ڣ<EFBFBD>3-UDP<EFBFBD><EFBFBD>4-TCPServer
|
||||
/// 选择,1-TCPCLIENT,2-串口,3-UDP,4-TCPServer
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ChannelEnum Channel { get; set; }
|
||||
@@ -65,12 +65,12 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
|
||||
public override ThingsGateway.Foundation.IReadWriteDevice Plc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ģ<EFBFBD><EFBFBD>
|
||||
/// 模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>
|
||||
/// 自定义模板
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment OtherContent { get; set; }
|
||||
@@ -100,7 +100,7 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
|
||||
TcpServerPage.LogAction = LogOut;
|
||||
if (UdpSessionPage != null)
|
||||
UdpSessionPage.LogAction = LogOut;
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
@@ -127,7 +127,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
/// 导入设备
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
public async Task DeviceImportAsync(CollectDevice data)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -145,7 +145,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
/// 导入变量
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(List<DeviceVariable> data)
|
||||
public async Task DeviceVariableImportAsync(List<DeviceVariable> data)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -159,6 +159,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 导出
|
||||
/// </summary>
|
||||
@@ -187,6 +188,51 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
|
||||
isDownExport = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出到excel
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
{
|
||||
try
|
||||
{
|
||||
isDownExport = true;
|
||||
StateHasChanged();
|
||||
using var memoryStream = await CollectDeviceService.ExportFileAsync(new List<CollectDevice>() { data });
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
_helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
|
||||
await _helper.InvokeVoidAsync("downloadFileFromStream", $"设备导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isDownExport = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出到excel
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceVariableExportAsync(List<DeviceVariable> data, string devName)
|
||||
{
|
||||
try
|
||||
{
|
||||
isDownExport = true;
|
||||
StateHasChanged();
|
||||
using var memoryStream = await VariableService.ExportFileAsync(data, devName);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
_helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
|
||||
await _helper.InvokeVoidAsync("downloadFileFromStream", $"变量导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isDownExport = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void LogOut(TouchSocket.Core.LogLevel logLevel, object source, string message, Exception exception)
|
||||
{
|
||||
|
@@ -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,7 +20,7 @@ namespace ThingsGateway.Blazor;
|
||||
public partial class SerialClientPage
|
||||
{
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 日志输出
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
@@ -36,7 +36,7 @@ public partial class SerialClientPage
|
||||
SerialClient.SafeDispose();
|
||||
}
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SerialClient GetSerialClient()
|
||||
@@ -47,7 +47,7 @@ public partial class SerialClientPage
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetSerialProperty(serialProperty);
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//载入配置
|
||||
SerialClient.Setup(config);
|
||||
return SerialClient;
|
||||
}
|
||||
@@ -78,8 +78,7 @@ public partial class SerialClientPage
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
config?.Dispose();
|
||||
config = new TouchSocketConfig();
|
||||
config ??= new TouchSocketConfig();
|
||||
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
|
@@ -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
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ThingsGateway.Blazor;
|
||||
public partial class TcpClientPage
|
||||
{
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 日志输出
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
@@ -33,7 +33,7 @@ public partial class TcpClientPage
|
||||
/// </summary>
|
||||
private string IP = "127.0.0.1";
|
||||
/// <summary>
|
||||
/// <EFBFBD>˿<EFBFBD>
|
||||
/// 端口
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Port { get; set; } = 502;
|
||||
@@ -73,18 +73,17 @@ public partial class TcpClientPage
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TcpClientEx GetTcpClient()
|
||||
{
|
||||
config?.Dispose();
|
||||
config = new TouchSocketConfig();
|
||||
config ??= new TouchSocketConfig();
|
||||
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetRemoteIPHost(new IPHost(IP + ":" + Port)).SetBufferLength(300);
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//载入配置
|
||||
TcpClientEx.Setup(config);
|
||||
return TcpClientEx;
|
||||
}
|
||||
|
@@ -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
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ThingsGateway.Blazor;
|
||||
public partial class TcpServerPage
|
||||
{
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 日志输出
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
@@ -62,19 +62,18 @@ public partial class TcpServerPage
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TcpService GetTcpServer()
|
||||
{
|
||||
config?.Dispose();
|
||||
config = new TouchSocketConfig();
|
||||
config ??= new TouchSocketConfig();
|
||||
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) });
|
||||
config.SetBufferLength(300);
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//载入配置
|
||||
TcpServer.Setup(config);
|
||||
return TcpServer;
|
||||
}
|
||||
|
@@ -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
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ThingsGateway.Blazor;
|
||||
public partial class UdpSessionPage : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 日志输出
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
@@ -62,19 +62,18 @@ public partial class UdpSessionPage : IDisposable
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UdpSession GetUdpSession()
|
||||
{
|
||||
config?.Dispose();
|
||||
config = new TouchSocketConfig();
|
||||
config ??= new TouchSocketConfig();
|
||||
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
|
||||
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
config.SetRemoteIPHost(new IPHost(ip + ":" + port)).SetBufferLength(300);
|
||||
config.SetBindIPHost(new IPHost(0));
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//载入配置
|
||||
UdpSession.Setup(config);
|
||||
return UdpSession;
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@
|
||||
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_collectDeviceGroupSearchName"
|
||||
Outlined Label=@typeof(CollectDevice).GetDescription(nameof(CollectDevice.DeviceGroup)) />
|
||||
</MCardTitle>
|
||||
|
||||
<MTreeview Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight + 240}px; overflow-y:auto)") Dense TItem="string" TKey="string" ActiveChanged=@(async a=>
|
||||
{
|
||||
if(_collectDeviceGroup!=a.FirstOrDefault())
|
||||
|
@@ -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
|
||||
|
||||
@@ -32,7 +32,7 @@ using ThingsGateway.Application;
|
||||
namespace ThingsGateway.Blazor;
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD>豸״̬ҳ<EFBFBD><EFBFBD>
|
||||
/// 设备状态页面
|
||||
/// </summary>
|
||||
public partial class DeviceStatusPage : IDisposable
|
||||
{
|
||||
@@ -110,7 +110,7 @@ public partial class DeviceStatusPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?");
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?");
|
||||
if (confirm)
|
||||
{
|
||||
isAllRestart = true;
|
||||
@@ -142,8 +142,8 @@ public partial class DeviceStatusPage : IDisposable
|
||||
}
|
||||
async Task ConfigAsync(long devId, bool? isStart)
|
||||
{
|
||||
var str = isStart == true ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>ͣ";
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"ȷ<EFBFBD><EFBFBD>{str}?");
|
||||
var str = isStart == true ? "启动" : "暂停";
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"确定{str}?");
|
||||
if (confirm)
|
||||
{
|
||||
CollectDeviceHostService.ConfigDeviceThread(devId, isStart == true);
|
||||
@@ -167,19 +167,19 @@ public partial class DeviceStatusPage : IDisposable
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
Helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
|
||||
await Helper.InvokeVoidAsync("downloadFileFromStream", $"<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.txt", streamRef);
|
||||
await Helper.InvokeVoidAsync("downloadFileFromStream", $"报文导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.txt", streamRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isDownExport = false;
|
||||
}
|
||||
}
|
||||
//ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//去除单个采集重启
|
||||
//async Task RestartAsync(long devId)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?");
|
||||
// var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?");
|
||||
// if (confirm)
|
||||
// {
|
||||
// isRestart = true;
|
||||
@@ -199,7 +199,6 @@ public partial class DeviceStatusPage : IDisposable
|
||||
// await MainLayout.StateHasChangedAsync();
|
||||
// }
|
||||
//}
|
||||
|
||||
private async Task RunTimerAsync()
|
||||
{
|
||||
while (await _periodicTimer.WaitForNextTickAsync())
|
||||
@@ -232,8 +231,8 @@ public partial class DeviceStatusPage : IDisposable
|
||||
|
||||
async Task UpConfigAsync(long devId, bool? isStart)
|
||||
{
|
||||
var str = isStart == true ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>ͣ";
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"ȷ<EFBFBD><EFBFBD>{str}?");
|
||||
var str = isStart == true ? "启动" : "暂停";
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"确定{str}?");
|
||||
if (confirm)
|
||||
{
|
||||
UploadDeviceHostService.ConfigDeviceThread(devId, isStart == true);
|
||||
@@ -254,7 +253,7 @@ public partial class DeviceStatusPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?");
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?");
|
||||
if (confirm)
|
||||
{
|
||||
isRestart = true;
|
||||
|
@@ -180,8 +180,41 @@ else
|
||||
}
|
||||
|
||||
</ItemColTemplate>
|
||||
|
||||
<Detailemplate>
|
||||
@{
|
||||
switch (context.Item1.Value)
|
||||
{
|
||||
case nameof(DeviceVariable.DeviceId):
|
||||
<tr @key="context.Item1.Text">
|
||||
<td class="text-start table-minwidth">
|
||||
@context.Item1.Text
|
||||
</td>
|
||||
<td class="text-start ">
|
||||
<div style="word-break:break-all; white-space:pre-wrap;">
|
||||
@(App.GetService<ICollectDeviceService>().GetNameById(context.Item2.ToLong()))
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
break;
|
||||
default:
|
||||
<tr @key="context.Item1.Text">
|
||||
<td class="text-start table-minwidth">
|
||||
@context.Item1.Text
|
||||
</td>
|
||||
<td class="text-start ">
|
||||
<div style="word-break:break-all; white-space:pre-wrap;">
|
||||
@context.Item2
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
</Detailemplate>
|
||||
</AppDataTable>
|
||||
;
|
||||
;
|
||||
return renderFragment;
|
||||
}
|
||||
|
||||
|
@@ -61,6 +61,7 @@ else
|
||||
</span>
|
||||
</LabelContent>
|
||||
</MTreeview>
|
||||
|
||||
</MCard>
|
||||
</MCol>
|
||||
<MCol Md=10 Cols="12">
|
||||
@@ -119,7 +120,38 @@ else
|
||||
}
|
||||
|
||||
</ItemColTemplate>
|
||||
<Detailemplate>
|
||||
@{
|
||||
switch (context.Item1.Value)
|
||||
{
|
||||
case nameof(DeviceVariable.DeviceId):
|
||||
<tr @key="context.Item1.Text">
|
||||
<td class="text-start table-minwidth">
|
||||
@context.Item1.Text
|
||||
</td>
|
||||
<td class="text-start ">
|
||||
<div style="word-break:break-all; white-space:pre-wrap;">
|
||||
@(App.GetService<ICollectDeviceService>().GetNameById(context.Item2.ToLong()))
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
break;
|
||||
default:
|
||||
<tr @key="context.Item1.Text">
|
||||
<td class="text-start table-minwidth">
|
||||
@context.Item1.Text
|
||||
</td>
|
||||
<td class="text-start ">
|
||||
<div style="word-break:break-all; white-space:pre-wrap;">
|
||||
@context.Item2
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
</Detailemplate>
|
||||
</AppDataTable>
|
||||
|
||||
;
|
||||
|
@@ -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
|
||||
|
||||
@@ -28,7 +28,7 @@ using ThingsGateway.Application;
|
||||
|
||||
namespace ThingsGateway.Blazor;
|
||||
/// <summary>
|
||||
/// ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ
|
||||
/// 实时数据页
|
||||
/// </summary>
|
||||
public partial class DeviceVariableRunTimePage
|
||||
{
|
||||
@@ -37,13 +37,13 @@ public partial class DeviceVariableRunTimePage
|
||||
List<DeviceTree> _deviceGroups = new();
|
||||
string _searchName;
|
||||
/// <summary>
|
||||
/// <EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[SupplyParameterFromQuery]
|
||||
public string DeviceName { get; set; }
|
||||
/// <summary>
|
||||
/// <EFBFBD>ϴ<EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 上传设备名称
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[SupplyParameterFromQuery]
|
||||
@@ -149,15 +149,23 @@ public partial class DeviceVariableRunTimePage
|
||||
private EventCallback<string> WriteValueAsync;
|
||||
private async Task OnWriteValueAsync(DeviceVariableRunTime tag, string value)
|
||||
{
|
||||
var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", new KeyValuePair<string, string>(tag.Name, value), true);
|
||||
if (!data.IsSuccess)
|
||||
var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}",
|
||||
|
||||
new Dictionary<string, string>()
|
||||
{
|
||||
|
||||
{ tag.Name, value}
|
||||
}
|
||||
|
||||
, true);
|
||||
if (data.Count > 0 && !data.FirstOrDefault().Value.IsSuccess)
|
||||
{
|
||||
throw new(data.Message);
|
||||
throw new(data.FirstOrDefault().Value.Message);
|
||||
}
|
||||
}
|
||||
private async Task WriteAsync(DeviceVariableRunTime collectVariableRunTime)
|
||||
{
|
||||
// <EFBFBD><EFBFBD><EFBFBD>첽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD>
|
||||
// 将异步方法添加到事件回调上
|
||||
WriteValueAsync = EventCallback.Factory.Create<string>(this, value => OnWriteValueAsync(collectVariableRunTime, value));
|
||||
await PopupService.OpenAsync(typeof(WriteValue), new Dictionary<string, object>()
|
||||
{
|
||||
|
@@ -32,7 +32,7 @@
|
||||
@layout MainLayout
|
||||
|
||||
<MRow NoGutters>
|
||||
<MCol Md=@(IsShowTreeView?4:0)>
|
||||
<MCol Md=@(IsShowTreeView?3:0)>
|
||||
<MCard Show=IsShowTreeView Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight}px);border-radius:0px;")>
|
||||
<MCardTitle>
|
||||
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_searchName" Outlined Label=@typeof(CollectDevice).GetDescription(nameof(CollectDevice.PluginId)) />
|
||||
@@ -62,7 +62,7 @@
|
||||
</MTreeview>
|
||||
</MCard>
|
||||
</MCol>
|
||||
<MCol Md=@(IsShowTreeView?8:12)>
|
||||
<MCol Md=@(IsShowTreeView?9:12)>
|
||||
<MCard Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight}px);border-radius:0px;")>
|
||||
<MCard Class="mb-3 pa-2 text-h6" Elevation="0" Flat Rounded="false">
|
||||
<MRow Align="AlignTypes.Center" Class="mt-1">
|
||||
|
@@ -130,7 +130,7 @@
|
||||
<MCard Elevation="1" Class="ma-2">
|
||||
<MCardSubtitle Class=@("text-h6")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>"当前内存/磁盘信息</span>
|
||||
<span>当前内存/磁盘信息</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
<MDivider></MDivider>
|
||||
|
@@ -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
|
||||
|
||||
@@ -19,7 +19,7 @@ using ThingsGateway.Application;
|
||||
namespace ThingsGateway.Blazor;
|
||||
|
||||
/// <summary>
|
||||
/// Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣҳ<EFBFBD><EFBFBD>
|
||||
/// 硬件信息页面
|
||||
/// </summary>
|
||||
public partial class HardwareInfoPage
|
||||
{
|
||||
|
@@ -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
|
||||
|
||||
@@ -25,7 +25,7 @@ using ThingsGateway.Application;
|
||||
namespace ThingsGateway.Blazor;
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD>ʷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
||||
/// 历史报警页面
|
||||
/// </summary>
|
||||
public partial class HistoryAlarmPage
|
||||
{
|
||||
@@ -75,7 +75,7 @@ public partial class HistoryAlarmPage
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("<EFBFBD><EFBFBD>ѯʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>" + ex.Message, AlertTypes.Warning));
|
||||
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("查询失败,请检查网络连接:" + ex.Message, AlertTypes.Warning));
|
||||
return new()
|
||||
{
|
||||
Current = 1,
|
||||
|
@@ -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
|
||||
|
||||
@@ -23,7 +23,7 @@ using ThingsGateway.Application;
|
||||
|
||||
namespace ThingsGateway.Blazor;
|
||||
/// <summary>
|
||||
/// ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
||||
/// 时序库页面
|
||||
/// </summary>
|
||||
public partial class HistoryValuePage
|
||||
{
|
||||
@@ -74,7 +74,7 @@ public partial class HistoryValuePage
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("<EFBFBD><EFBFBD>ѯʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>" + ex.Message, AlertTypes.Warning));
|
||||
await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("查询失败,请检查网络连接:" + ex.Message, AlertTypes.Warning));
|
||||
return new()
|
||||
{
|
||||
Current = 1,
|
||||
|
@@ -149,6 +149,7 @@
|
||||
<MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.ReadExpressions />
|
||||
|
||||
</MCol>
|
||||
|
||||
<MCol Md=6 Cols=12 class="px-1">
|
||||
|
||||
<MSubheader Class="font-weight-black"> @(context.Description(x => x.WriteExpressions)) </MSubheader>
|
||||
|
@@ -96,7 +96,7 @@ public partial class MemoryVariablePage
|
||||
|
||||
Task<Dictionary<string, ImportPreviewOutputBase>> DeviceImportAsync(IBrowserFile file)
|
||||
{
|
||||
return VariableService.PreviewAsync(file);
|
||||
return VariableService.MemoryVariablePreviewAsync(file);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
||||
@@ -22,7 +22,7 @@ using ThingsGateway.Application;
|
||||
|
||||
namespace ThingsGateway.Blazor;
|
||||
/// <summary>
|
||||
/// ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 实时报警
|
||||
/// </summary>
|
||||
public partial class RealAlarmPage
|
||||
{
|
||||
|
@@ -428,13 +428,13 @@
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.WriteAsync">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceExportAsync(ThingsGateway.Application.CollectDevice)">
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DeviceImportAsync(ThingsGateway.Application.CollectDevice)">
|
||||
<summary>
|
||||
导入设备
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceExportAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DeviceVariableImportAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable})">
|
||||
<summary>
|
||||
导入变量
|
||||
</summary>
|
||||
@@ -447,6 +447,18 @@
|
||||
<param name="values"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceExportAsync(ThingsGateway.Application.CollectDevice)">
|
||||
<summary>
|
||||
导出到excel
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.DownDeviceVariableExportAsync(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariable},System.String)">
|
||||
<summary>
|
||||
导出到excel
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.DriverDebugUIBase.LogOut(TouchSocket.Core.LogLevel,System.Object,System.String,System.Exception)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
|
@@ -30,7 +30,7 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
|
||||
public ReadWriteDevicesSerialBase(SerialClient serialClient)
|
||||
{
|
||||
SerialClient = serialClient;
|
||||
WaitingClientEx = SerialClient.GetWaitingClientEx(new());
|
||||
WaitingClientEx = SerialClient.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
|
||||
SerialClient.Connecting -= Connecting;
|
||||
SerialClient.Connected -= Connected;
|
||||
|
@@ -26,7 +26,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesClientBase
|
||||
public ReadWriteDevicesTcpClientBase(TcpClientEx tcpClient)
|
||||
{
|
||||
TcpClientEx = tcpClient;
|
||||
WaitingClientEx = TcpClientEx.GetWaitingClientEx(new());
|
||||
WaitingClientEx = TcpClientEx.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
TcpClientEx.Connecting -= Connecting;
|
||||
TcpClientEx.Connected -= Connected;
|
||||
TcpClientEx.Disconnecting -= Disconnecting;
|
||||
|
@@ -24,10 +24,8 @@ public abstract class ReadWriteDevicesUdpBase : ReadWriteDevicesClientBase
|
||||
/// <inheritdoc cref="ReadWriteDevicesUdpBase"/>
|
||||
public ReadWriteDevicesUdpBase(UdpSession udpSession)
|
||||
{
|
||||
|
||||
UdpSession = udpSession;
|
||||
WaitingClientEx = UdpSession.GetWaitingClientEx(new());
|
||||
|
||||
WaitingClientEx = UdpSession.GetWaitingClientEx(new() { BreakTrigger = true });
|
||||
SetDataAdapter();
|
||||
}
|
||||
/// <summary>
|
||||
|
@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation;
|
||||
/// <summary>
|
||||
/// 自增
|
||||
/// </summary>
|
||||
public sealed class EasyIncrementCount : DisposableObject
|
||||
public sealed class EasyIncrementCount : IDisposable
|
||||
{
|
||||
private long current = 0;
|
||||
private readonly EasyLock easyLock;
|
||||
@@ -30,6 +30,11 @@ public sealed class EasyIncrementCount : DisposableObject
|
||||
IncreaseTick = tick;
|
||||
easyLock = new EasyLock();
|
||||
}
|
||||
/// <inheritdoc cref="EasyIncrementCount"/>
|
||||
~EasyIncrementCount()
|
||||
{
|
||||
easyLock.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tick
|
||||
@@ -117,10 +122,10 @@ public sealed class EasyIncrementCount : DisposableObject
|
||||
}
|
||||
easyLock.Release();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
public void Dispose()
|
||||
{
|
||||
easyLock.SafeDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
@@ -15,11 +15,15 @@ namespace ThingsGateway.Foundation;
|
||||
/// <summary>
|
||||
/// EasyLock,使用轻量级SemaphoreSlim锁,只允许一个并发量,并记录并发信息
|
||||
/// </summary>
|
||||
public sealed class EasyLock : DisposableObject
|
||||
public sealed class EasyLock : IDisposable
|
||||
{
|
||||
private static long lockWaitCount;
|
||||
private readonly Lazy<SemaphoreSlim> m_waiterLock = new(() => new SemaphoreSlim(1));
|
||||
|
||||
/// <inheritdoc/>
|
||||
~EasyLock()
|
||||
{
|
||||
m_waiterLock.Value.SafeDispose();
|
||||
}
|
||||
/// <summary>
|
||||
/// 当前正在等待的数量
|
||||
/// </summary>
|
||||
@@ -28,6 +32,13 @@ public sealed class EasyLock : DisposableObject
|
||||
/// 当前锁是否在等待当中
|
||||
/// </summary>
|
||||
public bool IsWaitting => m_waiterLock.Value.CurrentCount == 0;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
m_waiterLock.Value.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离开锁
|
||||
/// </summary>
|
||||
@@ -73,10 +84,5 @@ public sealed class EasyLock : DisposableObject
|
||||
await m_waiterLock.Value.WaitAsync(timeSpan, token);
|
||||
Interlocked.Decrement(ref lockWaitCount);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
m_waiterLock.Value.SafeDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
}
|
@@ -159,7 +159,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlguin.OnTcpDisconnected), this, e);
|
||||
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -325,27 +325,33 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
if (!DisposedValue)
|
||||
{
|
||||
privateEasyLock.Wait();
|
||||
if (this.m_online)
|
||||
try
|
||||
{
|
||||
this.m_online = false;
|
||||
this.MainSocket.TryClose();
|
||||
this.PrivateOnDisconnecting(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
|
||||
this.MainSocket.SafeDispose();
|
||||
this.m_delaySender.SafeDispose();
|
||||
this.m_workStream.SafeDispose();
|
||||
this.DataHandlingAdapter.SafeDispose();
|
||||
this.PluginsManager.SafeDispose();
|
||||
this.PrivateOnDisconnected(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
privateEasyLock.Wait();
|
||||
if (this.m_online)
|
||||
{
|
||||
this.m_online = false;
|
||||
this.MainSocket.TryClose();
|
||||
this.PrivateOnDisconnecting(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
|
||||
this.MainSocket.SafeDispose();
|
||||
this.m_delaySender.SafeDispose();
|
||||
this.m_workStream.SafeDispose();
|
||||
this.DataHandlingAdapter.SafeDispose();
|
||||
this.PluginsManager.SafeDispose();
|
||||
this.PrivateOnDisconnected(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
privateEasyLock.Release();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
privateEasyLock.Release();
|
||||
}
|
||||
privateEasyLock.SafeDispose();
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
|
@@ -12,12 +12,14 @@
|
||||
|
||||
|
||||
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
|
||||
internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClient> where TClient : IClient, IDefaultSender, ISender
|
||||
{
|
||||
private readonly Func<ResponsedData, bool> m_func;
|
||||
private readonly SemaphoreSlim m_lock = new(1);
|
||||
private readonly EasyLock easyLock = new();
|
||||
private readonly WaitData<ResponsedData> m_waitData = new WaitData<ResponsedData>();
|
||||
private readonly WaitDataAsync<ResponsedData> m_waitDataAsync = new WaitDataAsync<ResponsedData>();
|
||||
|
||||
@@ -52,6 +54,8 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
|
||||
{
|
||||
this.Client = default;
|
||||
this.m_waitData.SafeDispose();
|
||||
this.m_waitDataAsync.SafeDispose();
|
||||
this.easyLock.SafeDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
@@ -66,7 +70,11 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
|
||||
this.m_breaked = true;
|
||||
this.Cancel();
|
||||
}
|
||||
|
||||
private void OnSerialClientDisconnected(ISerialClientBase client, DisconnectEventArgs e)
|
||||
{
|
||||
this.m_breaked = true;
|
||||
this.Cancel();
|
||||
}
|
||||
private bool OnHandleRawBuffer(ByteBlock byteBlock)
|
||||
{
|
||||
var responsedData = new ResponsedData(byteBlock.ToArray(), null, true);
|
||||
@@ -114,14 +122,17 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
|
||||
{
|
||||
try
|
||||
{
|
||||
m_lock.Wait();
|
||||
easyLock.Wait();
|
||||
this.m_breaked = false;
|
||||
this.Reset();
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
|
||||
{
|
||||
tcpClient.Disconnected += this.OnDisconnected;
|
||||
}
|
||||
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
|
||||
{
|
||||
serialClient.Disconnected += this.OnSerialClientDisconnected;
|
||||
}
|
||||
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
|
||||
{
|
||||
this.Client.OnHandleReceivedData += this.OnHandleReceivedData;
|
||||
@@ -174,12 +185,15 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.Release();
|
||||
easyLock.Release();
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
|
||||
{
|
||||
tcpClient.Disconnected -= this.OnDisconnected;
|
||||
}
|
||||
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
|
||||
{
|
||||
serialClient.Disconnected -= this.OnSerialClientDisconnected;
|
||||
}
|
||||
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
|
||||
{
|
||||
this.Client.OnHandleReceivedData -= this.OnHandleReceivedData;
|
||||
@@ -191,6 +205,8 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ResponsedData SendThenResponse(byte[] buffer, int timeout = 1000 * 5, CancellationToken token = default)
|
||||
{
|
||||
return this.SendThenResponse(buffer, 0, buffer.Length, timeout, token);
|
||||
@@ -209,14 +225,17 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
|
||||
{
|
||||
try
|
||||
{
|
||||
await m_lock.WaitAsync();
|
||||
await easyLock.WaitAsync();
|
||||
this.m_breaked = false;
|
||||
this.Reset();
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
|
||||
{
|
||||
tcpClient.Disconnected += this.OnDisconnected;
|
||||
}
|
||||
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
|
||||
{
|
||||
serialClient.Disconnected += this.OnSerialClientDisconnected;
|
||||
}
|
||||
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
|
||||
{
|
||||
this.Client.OnHandleReceivedData += this.OnHandleReceivedData;
|
||||
@@ -269,12 +288,15 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.Release();
|
||||
easyLock.Release();
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient)
|
||||
{
|
||||
tcpClient.Disconnected -= this.OnDisconnected;
|
||||
}
|
||||
|
||||
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
|
||||
{
|
||||
serialClient.Disconnected -= this.OnSerialClientDisconnected;
|
||||
}
|
||||
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
|
||||
{
|
||||
this.Client.OnHandleReceivedData -= this.OnHandleReceivedData;
|
||||
|
@@ -46,19 +46,6 @@ public static class StringExtensions
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将16进制的字符转换为int32。
|
||||
/// </summary>
|
||||
/// <param name="hexString"></param>
|
||||
/// <returns></returns>
|
||||
public static int ByHexStringToInt32(this string hexString)
|
||||
{
|
||||
if (string.IsNullOrEmpty(hexString))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
return int.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="Path.Combine(string[])"/>
|
||||
/// 并把\\转为/
|
||||
|
@@ -15,6 +15,17 @@ namespace ThingsGateway.Foundation.Extension;
|
||||
/// <inheritdoc/>
|
||||
public static class OperResultExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 复制信息,包含第一个泛型类
|
||||
/// </summary>
|
||||
public static OperResult<T1> Copy<T1, T2>(this OperResult<T1, T2> result)
|
||||
{
|
||||
OperResult<T1> result1 = new(result.ResultCode, result.Message)
|
||||
{
|
||||
Content = result.Content1
|
||||
};
|
||||
return result1;
|
||||
}
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
|
@@ -172,7 +172,7 @@ public class SerialClientBase : BaseSerial, ISerialClient
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlguin.OnTcpDisconnected), this, e);
|
||||
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e);
|
||||
}
|
||||
private void PrivateOnDisconnecting(DisconnectEventArgs e)
|
||||
{
|
||||
|
@@ -45,4 +45,9 @@ public class SerialProperty
|
||||
/// </summary>
|
||||
[Description("停止位")]
|
||||
public StopBits StopBits { get; set; } = StopBits.One;
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{PortName}[{BaudRate},{DataBits},{StopBits},{Parity}]";
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net45;net6.0;net7.0</TargetFrameworks>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks>
|
||||
<OpenApiGenerateDocuments>false</OpenApiGenerateDocuments>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="TouchSocket" Version="2.0.0-beta.120" />
|
||||
<PackageReference Include="TouchSocket" Version="2.0.0-beta.138" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)'!='net45'">
|
||||
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
|
||||
|
@@ -588,6 +588,9 @@
|
||||
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.#ctor(System.Int64,System.Int64,System.Int32)">
|
||||
<inheritdoc cref="T:ThingsGateway.Foundation.EasyIncrementCount"/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.Finalize">
|
||||
<inheritdoc cref="T:ThingsGateway.Foundation.EasyIncrementCount"/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.EasyIncrementCount.IncreaseTick">
|
||||
<summary>
|
||||
Tick
|
||||
@@ -623,7 +626,7 @@
|
||||
重置当前序号的初始值
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.Dispose(System.Boolean)">
|
||||
<member name="M:ThingsGateway.Foundation.EasyIncrementCount.Dispose">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.EasyLock">
|
||||
@@ -631,6 +634,9 @@
|
||||
EasyLock,使用轻量级SemaphoreSlim锁,只允许一个并发量,并记录并发信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.EasyLock.Finalize">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.EasyLock.LockWaitCount">
|
||||
<summary>
|
||||
当前正在等待的数量
|
||||
@@ -641,6 +647,9 @@
|
||||
当前锁是否在等待当中
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.EasyLock.Dispose">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.EasyLock.Release">
|
||||
<summary>
|
||||
离开锁
|
||||
@@ -666,9 +675,6 @@
|
||||
进入锁
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.EasyLock.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.TcpClientEx">
|
||||
<summary>
|
||||
简单TCP客户端
|
||||
@@ -1283,13 +1289,6 @@
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.ByHexStringToInt32(System.String)">
|
||||
<summary>
|
||||
将16进制的字符转换为int32。
|
||||
</summary>
|
||||
<param name="hexString"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.CombinePathOS(System.String,System.String[])">
|
||||
<summary>
|
||||
<inheritdoc cref="M:System.IO.Path.Combine(System.String[])"/>
|
||||
@@ -1313,6 +1312,11 @@
|
||||
<member name="T:ThingsGateway.Foundation.Extension.OperResultExtensions">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Extension.OperResultExtensions.Copy``2(ThingsGateway.Foundation.OperResult{``0,``1})">
|
||||
<summary>
|
||||
复制信息,包含第一个泛型类
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Extension.OperResultExtensions.Copy``1(ThingsGateway.Foundation.OperResult)">
|
||||
<summary>
|
||||
复制信息,不包含泛型类
|
||||
@@ -2288,6 +2292,9 @@
|
||||
停止位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Serial.SerialProperty.ToString">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.SerialPortExtensions">
|
||||
<summary>
|
||||
SocketExtension
|
||||
|
@@ -31,11 +31,11 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
private DataFormat dataFormat;
|
||||
/// <inheritdoc/>
|
||||
[JsonIgnore]
|
||||
public Encoding Encoding { get; set; } = Encoding.UTF8;
|
||||
public virtual Encoding Encoding { get; set; } = Encoding.UTF8;
|
||||
/// <inheritdoc/>
|
||||
public BcdFormat? BcdFormat { get; set; }
|
||||
public virtual BcdFormat? BcdFormat { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public int StringLength { get; set; }
|
||||
public virtual int StringLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@@ -55,7 +55,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataFormat DataFormat
|
||||
public virtual DataFormat DataFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -69,9 +69,9 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public EndianType EndianType => endianType;
|
||||
public virtual EndianType EndianType => endianType;
|
||||
/// <inheritdoc/>
|
||||
public bool IsStringReverseByteWord { get; set; }
|
||||
public virtual bool IsStringReverseByteWord { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual IThingsGatewayBitConverter CreateByDateFormat(DataFormat dataFormat)
|
||||
@@ -86,7 +86,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return byteConverter;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(bool value)
|
||||
public virtual byte[] GetBytes(bool value)
|
||||
{
|
||||
return GetBytes(new bool[1]
|
||||
{
|
||||
@@ -95,13 +95,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(bool[] values)
|
||||
public virtual byte[] GetBytes(bool[] values)
|
||||
{
|
||||
return values?.BoolArrayToByte();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(short value)
|
||||
public virtual byte[] GetBytes(short value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (!IsSameOfSet())
|
||||
@@ -111,7 +111,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return bytes;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(short[] value)
|
||||
public virtual byte[] GetBytes(short[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -123,7 +123,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ushort value)
|
||||
public virtual byte[] GetBytes(ushort value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (!IsSameOfSet())
|
||||
@@ -133,7 +133,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return bytes;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ushort[] value)
|
||||
public virtual byte[] GetBytes(ushort[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -144,12 +144,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(int value)
|
||||
public virtual byte[] GetBytes(int value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(int[] value)
|
||||
public virtual byte[] GetBytes(int[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -160,12 +160,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(uint value)
|
||||
public virtual byte[] GetBytes(uint value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(uint[] value)
|
||||
public virtual byte[] GetBytes(uint[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -176,12 +176,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(long value)
|
||||
public virtual byte[] GetBytes(long value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(long[] value)
|
||||
public virtual byte[] GetBytes(long[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -192,12 +192,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ulong value)
|
||||
public virtual byte[] GetBytes(ulong value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ulong[] value)
|
||||
public virtual byte[] GetBytes(ulong[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -208,12 +208,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(float value)
|
||||
public virtual byte[] GetBytes(float value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(float[] value)
|
||||
public virtual byte[] GetBytes(float[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -224,12 +224,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(double value)
|
||||
public virtual byte[] GetBytes(double value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(double[] value)
|
||||
public virtual byte[] GetBytes(double[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -240,7 +240,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(string value)
|
||||
public virtual byte[] GetBytes(string value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
@@ -280,7 +280,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsSameOfSet()
|
||||
public virtual bool IsSameOfSet()
|
||||
{
|
||||
return !(BitConverter.IsLittleEndian ^ (endianType == EndianType.Little));
|
||||
}
|
||||
@@ -288,7 +288,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ToBoolean(byte[] buffer, int offset)
|
||||
public virtual bool ToBoolean(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[buffer.Length];
|
||||
Array.Copy(buffer, 0, bytes, 0, buffer.Length);
|
||||
@@ -296,7 +296,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte ToByte(byte[] buffer, int offset)
|
||||
public virtual byte ToByte(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[1];
|
||||
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
|
||||
@@ -304,7 +304,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] ToByte(byte[] buffer, int offset, int length)
|
||||
public virtual byte[] ToByte(byte[] buffer, int offset, int length)
|
||||
{
|
||||
byte[] bytes = new byte[length];
|
||||
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
|
||||
@@ -317,7 +317,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public double ToDouble(byte[] buffer, int offset)
|
||||
public virtual double ToDouble(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat8(buffer, offset);
|
||||
|
||||
@@ -325,7 +325,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short ToInt16(byte[] buffer, int offset)
|
||||
public virtual short ToInt16(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
|
||||
@@ -337,7 +337,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int ToInt32(byte[] buffer, int offset)
|
||||
public virtual int ToInt32(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat4(buffer, offset);
|
||||
|
||||
@@ -345,14 +345,14 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long ToInt64(byte[] buffer, int offset)
|
||||
public virtual long ToInt64(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat8(buffer, offset);
|
||||
return BitConverter.ToInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public float ToSingle(byte[] buffer, int offset)
|
||||
public virtual float ToSingle(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat4(buffer, offset);
|
||||
|
||||
@@ -360,13 +360,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ToString(byte[] buffer)
|
||||
public virtual string ToString(byte[] buffer)
|
||||
{
|
||||
return ToString(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ToString(byte[] buffer, int offset, int length)
|
||||
public virtual string ToString(byte[] buffer, int offset, int length)
|
||||
{
|
||||
byte[] numArray = buffer.SelectMiddle(offset, length);
|
||||
if (BcdFormat != null)
|
||||
@@ -385,7 +385,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ushort ToUInt16(byte[] buffer, int offset)
|
||||
public virtual ushort ToUInt16(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
Array.Copy(buffer, offset, bytes, 0, 2);
|
||||
@@ -397,7 +397,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint ToUInt32(byte[] buffer, int offset)
|
||||
public virtual uint ToUInt32(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat4(buffer, offset);
|
||||
|
||||
@@ -405,7 +405,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong ToUInt64(byte[] buffer, int offset)
|
||||
public virtual ulong ToUInt64(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat8(buffer, offset);
|
||||
return BitConverter.ToUInt64(bytes, 0);
|
||||
@@ -508,7 +508,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool[] ToBoolean(byte[] buffer, int offset, int len)
|
||||
public virtual bool[] ToBoolean(byte[] buffer, int offset, int len)
|
||||
{
|
||||
bool[] flagArray = new bool[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -519,7 +519,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public double[] ToDouble(byte[] buffer, int offset, int len)
|
||||
public virtual double[] ToDouble(byte[] buffer, int offset, int len)
|
||||
{
|
||||
double[] numArray = new double[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -530,7 +530,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short[] ToInt16(byte[] buffer, int offset, int len)
|
||||
public virtual short[] ToInt16(byte[] buffer, int offset, int len)
|
||||
{
|
||||
short[] numArray = new short[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -541,7 +541,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int[] ToInt32(byte[] buffer, int offset, int len)
|
||||
public virtual int[] ToInt32(byte[] buffer, int offset, int len)
|
||||
{
|
||||
int[] numArray = new int[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -552,7 +552,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long[] ToInt64(byte[] buffer, int offset, int len)
|
||||
public virtual long[] ToInt64(byte[] buffer, int offset, int len)
|
||||
{
|
||||
long[] numArray = new long[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -562,7 +562,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public float[] ToSingle(byte[] buffer, int offset, int len)
|
||||
public virtual float[] ToSingle(byte[] buffer, int offset, int len)
|
||||
{
|
||||
float[] numArray = new float[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -573,7 +573,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ushort[] ToUInt16(byte[] buffer, int offset, int len)
|
||||
public virtual ushort[] ToUInt16(byte[] buffer, int offset, int len)
|
||||
{
|
||||
ushort[] numArray = new ushort[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -584,7 +584,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint[] ToUInt32(byte[] buffer, int offset, int len)
|
||||
public virtual uint[] ToUInt32(byte[] buffer, int offset, int len)
|
||||
{
|
||||
uint[] numArray = new uint[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -595,7 +595,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong[] ToUInt64(byte[] buffer, int offset, int len)
|
||||
public virtual ulong[] ToUInt64(byte[] buffer, int offset, int len)
|
||||
{
|
||||
ulong[] numArray = new ulong[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
|
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ModbusDemo</name>
|
||||
<name>DLT645Test</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
@@ -0,0 +1,112 @@
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Adapter.DLT645;
|
||||
using ThingsGateway.Foundation.Extension.Byte;
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
namespace DLT645Test
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
|
||||
await DLT645_2007ClientAsync();
|
||||
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
|
||||
private static async Task DLT645_2007ClientAsync()
|
||||
{
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config.SetRemoteIPHost(new IPHost("127.0.0.1:502"))//TCP/UDP链路才需要
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
}).SetBufferLength(1024);
|
||||
|
||||
var serialClient = new SerialClient();//链路对象
|
||||
serialClient.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
|
||||
DLT645_2007 dlt6452007 = new(serialClient)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
FrameTime = 0,
|
||||
CacheTimeout = 1000,
|
||||
ConnectTimeOut = 3000,
|
||||
TimeOut = 3000,
|
||||
EnableFEHead = true,
|
||||
};
|
||||
|
||||
#region 读写测试
|
||||
//测试读取写入
|
||||
Console.WriteLine("dlt6452007:" + dlt6452007.SerialClient.SerialProperty.ToJson());
|
||||
await TestAsync(dlt6452007);
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
private static async Task TestAsync(DLT645_2007 plc)
|
||||
{
|
||||
//下面的方法对应PLC读写协议对象都是通用的
|
||||
//注意下面的方法都带有CancellationToken传播,一般是在最后一个参数,默认为None
|
||||
|
||||
|
||||
//var bytes02010100Result = await plc.ReadAsync("03010100", 20);
|
||||
////返回带有是否成功等参数,实际数据在data.Content中
|
||||
//Console.WriteLine("bytes02010100Result:" + (bytes02010100Result.IsSuccess ? bytes02010100Result.Content.ToHexString() : bytes02010100Result.Message));
|
||||
//Console.WriteLine("bytes02010100Result:" + (bytes02010100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02010100Result.Content, 0) : bytes02010100Result.Message));
|
||||
|
||||
//var bytes02020100Result = await plc.ReadAsync("02020100", 20);
|
||||
////返回带有是否成功等参数,实际数据在data.Content中
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02020100Result.Content, 0) : bytes02020100Result.Message));
|
||||
|
||||
//var bytes02020100Result = await plc.ReadAsync("04000103", 1);
|
||||
////返回带有是否成功等参数,实际数据在data.Content中
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message));
|
||||
|
||||
|
||||
var test1 = await plc.ReadDeviceStationAsync();
|
||||
Console.WriteLine("bytes02020100Result:" + (test1.IsSuccess ? test1.Content : test1.Message));
|
||||
|
||||
var test2 = await plc.WriteDeviceStationAsync("311111111114");
|
||||
Console.WriteLine("bytes02020100Result:" + (test2.IsSuccess ? test2.Message : test2.Message));
|
||||
plc.BroadcastTime(DateTime.Now);
|
||||
plc.Station = "311111111114";
|
||||
|
||||
var test3 = await plc.WriteBaudRateAsync(19200);
|
||||
Console.WriteLine("bytes02020100Result:" + (test3.IsSuccess ? test3.Message : test3.Message));
|
||||
var test4 = await plc.FreezeAsync(DateTime.Now);
|
||||
Console.WriteLine("bytes02020100Result:" + (test4.IsSuccess ? test4.Message : test4.Message));
|
||||
|
||||
var test5 = await plc.WritePasswordAsync(1, "66666666", "11111111");
|
||||
Console.WriteLine("bytes02020100Result:" + (test5.IsSuccess ? test5.Message : test5.Message));
|
||||
plc.Password = "11111111";
|
||||
|
||||
|
||||
|
||||
var bytes02020100Result1 = await plc.ReadAsync("04000403", 1);
|
||||
//返回带有是否成功等参数,实际数据在data.Content中
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result1.IsSuccess ? bytes02020100Result1.Content.ToHexString() : bytes02020100Result1.Message));
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result1.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result1.Content) : bytes02020100Result1.Message));
|
||||
|
||||
var test = await plc.WriteAsync("04000403", "33");
|
||||
//返回带有是否成功等参数,实际数据在data.Content中
|
||||
Console.WriteLine("test:" + test.Message);
|
||||
var bytes02020100Result = await plc.ReadAsync("04000403", 1);
|
||||
//返回带有是否成功等参数,实际数据在data.Content中
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ModbusTest</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
@@ -12,7 +12,7 @@ namespace ModbusDemo
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
//await ModbusClientAsync();
|
||||
await ModbusClientAsync();
|
||||
|
||||
await ModbusServerAsync();
|
||||
|
@@ -7,8 +7,9 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
|
||||
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>OPCUAClientTest</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
@@ -0,0 +1,29 @@
|
||||
using ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
namespace ModbusDemo
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
OPCUAClient oPCUAClient = new(new EasyLogger(a => Console.WriteLine(a)))
|
||||
{
|
||||
OPCNode = new()
|
||||
{
|
||||
OPCUrl = "opc.tcp://desktop-p5gb4iq:50001/StandardServer",
|
||||
IsUseSecurity = true,
|
||||
}
|
||||
};
|
||||
await oPCUAClient.ConnectAsync();
|
||||
|
||||
var testData1 = await oPCUAClient.ReadJTokenValueAsync(new[] { "ns=2;i=2897" });
|
||||
await oPCUAClient.WriteNodeAsync(new()
|
||||
{
|
||||
{"ns=2;i=2897", testData1.FirstOrDefault().Item3 }
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Version>2.0.3.0</Version>
|
||||
<Version>2.1.0.0</Version>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,459 @@
|
||||
#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.Extension.Byte;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public class DLT645_2007 : ReadWriteDevicesSerialBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
/// <param name="serialClient"></param>
|
||||
public DLT645_2007(SerialClient serialClient) : base(serialClient)
|
||||
{
|
||||
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 组包缓存时间/ms
|
||||
/// </summary>
|
||||
[Description("组包缓存时间ms")]
|
||||
public int CacheTimeout { get; set; } = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
/// </summary>
|
||||
[Description("前导符报文头")]
|
||||
public bool EnableFEHead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 帧前时间ms
|
||||
/// </summary>
|
||||
[Description("帧前时间ms")]
|
||||
public int FrameTime { get; set; }
|
||||
/// <summary>
|
||||
/// 写入需操作员代码
|
||||
/// </summary>
|
||||
[Description("操作员代码")]
|
||||
public string OperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入密码
|
||||
/// </summary>
|
||||
[Description("写入密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯地址BCD码,一般应该是12个字符
|
||||
/// </summary>
|
||||
[Description("通讯地址")]
|
||||
public string Station { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription() => base.GetAddressDescription() + Environment.NewLine;
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, length, (byte)ControlCode.Read, Station);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter()
|
||||
{
|
||||
var dataHandleAdapter = new DLT645_2007DataHandleAdapter
|
||||
{
|
||||
EnableFEHead = EnableFEHead
|
||||
};
|
||||
SerialClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken token = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
Password ??= string.Empty;
|
||||
OperCode ??= string.Empty;
|
||||
if (Password.Length < 8)
|
||||
Password = Password.PadLeft(8, '0');
|
||||
if (OperCode.Length < 8)
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, 1, (byte)ControlCode.Write, Station, data, strArray);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, double value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, float value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, long value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, short value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public OperResult BroadcastTime(DateTime dateTime, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(token);
|
||||
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
SerialClient.Send(commandResult.Content);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取通信地址
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
|
||||
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改波特率
|
||||
/// </summary>
|
||||
/// <param name="baudRate"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
byte baudRateByte;
|
||||
switch (baudRate)
|
||||
{
|
||||
case 600: baudRateByte = 0x02; break;
|
||||
case 1200: baudRateByte = 0x04; break;
|
||||
case 2400: baudRateByte = 0x08; break;
|
||||
case 4800: baudRateByte = 0x10; break;
|
||||
case 9600: baudRateByte = 0x20; break;
|
||||
case 19200: baudRateByte = 0x40; break;
|
||||
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
|
||||
}
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新通信地址
|
||||
/// </summary>
|
||||
/// <param name="station"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="oldPassword"></param>
|
||||
/// <param name="newPassword"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
string str = $"04000C{level:D2}";
|
||||
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
|
||||
str.ByHexStringToBytes().Reverse().ToArray()
|
||||
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 控制码
|
||||
/// </summary>
|
||||
public enum ControlCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 读数据
|
||||
/// </summary>
|
||||
Read = 0x11,
|
||||
/// <summary>
|
||||
/// 读后续数据
|
||||
/// </summary>
|
||||
ReadSub = 0x12,
|
||||
/// <summary>
|
||||
/// 读站号
|
||||
/// </summary>
|
||||
ReadStation = 0x13,
|
||||
/// <summary>
|
||||
/// 写数据
|
||||
/// </summary>
|
||||
Write = 0x14,
|
||||
/// <summary>
|
||||
/// 写站号
|
||||
/// </summary>
|
||||
WriteStation = 0x15,
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
BroadcastTime = 0x08,
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
Freeze = 0x16,
|
||||
/// <summary>
|
||||
/// 更新波特率
|
||||
/// </summary>
|
||||
WriteBaudRate = 0x17,
|
||||
/// <summary>
|
||||
/// 更新密码
|
||||
/// </summary>
|
||||
WritePassword = 0x18,
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user