mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-11-02 08:33:59 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d33d900592 | ||
|
|
29365c4ef9 | ||
|
|
17a6189089 | ||
|
|
003b8a3763 | ||
|
|
1c7f8b5cab | ||
|
|
b7ff9ffca2 |
@@ -20,6 +20,7 @@ using System.Collections.Concurrent;
|
||||
using ThingsGateway.Extension;
|
||||
using ThingsGateway.FriendlyException;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
using ThingsGateway.SqlSugar;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
@@ -90,13 +91,12 @@ public sealed class OperDescAttribute : MoAttribute
|
||||
OperDescAttribute.WriteToQueue(log);
|
||||
}
|
||||
}
|
||||
|
||||
private static SqlSugarClient _db = DbContext.Db.GetConnectionScopeWithAttr<SysOperateLog>().CopyNew();
|
||||
/// <summary>
|
||||
/// 将日志消息写入数据库中
|
||||
/// </summary>
|
||||
private static async Task ProcessQueue()
|
||||
{
|
||||
var db = DbContext.Db.GetConnectionScopeWithAttr<SysOperateLog>().CopyNew();
|
||||
var appLifetime = App.RootServices!.GetService<IHostApplicationLifetime>()!;
|
||||
while (!appLifetime.ApplicationStopping.IsCancellationRequested)
|
||||
{
|
||||
@@ -105,7 +105,7 @@ public sealed class OperDescAttribute : MoAttribute
|
||||
var data = _logMessageQueue.ToListWithDequeue(); // 从日志队列中获取数据
|
||||
if (data.Count > 0)
|
||||
{
|
||||
await db.InsertableWithAttr(data).ExecuteCommandAsync(appLifetime.ApplicationStopping).ConfigureAwait(false);//入库
|
||||
await _db.InsertableWithAttr(data).ExecuteCommandAsync(appLifetime.ApplicationStopping).ConfigureAwait(false);//入库
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
/// <summary>OAuthOptions 配置类</summary>
|
||||
public abstract class AdminOAuthOptions : OAuthOptions
|
||||
{
|
||||
/// <summary>默认构造函数</summary>
|
||||
protected AdminOAuthOptions()
|
||||
{
|
||||
ConfigureClaims();
|
||||
this.Events.OnRemoteFailure = context =>
|
||||
{
|
||||
var redirectUri = string.IsNullOrEmpty(HomePath) ? "/" : HomePath;
|
||||
context.Response.Redirect(redirectUri);
|
||||
context.HandleResponse();
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>配置 Claims 映射</summary>
|
||||
protected virtual void ConfigureClaims()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual string GetName(JsonElement element)
|
||||
{
|
||||
JsonElement.ObjectEnumerator target = element.EnumerateObject();
|
||||
return target.TryGetValue("name");
|
||||
}
|
||||
|
||||
/// <summary>获得/设置 登陆后首页</summary>
|
||||
public string HomePath { get; set; } = "/";
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
public class GiteeOAuthUser
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Login { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Avatar_Url { get; set; }
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
public static class OAuthUserExtensions
|
||||
{
|
||||
public static GiteeOAuthUser ToAuthUser(this JsonElement element)
|
||||
{
|
||||
GiteeOAuthUser authUser = new GiteeOAuthUser();
|
||||
JsonElement.ObjectEnumerator target = element.EnumerateObject();
|
||||
authUser.Id = target.TryGetValue("id");
|
||||
authUser.Login = target.TryGetValue("login");
|
||||
authUser.Name = target.TryGetValue("name");
|
||||
authUser.Avatar_Url = target.TryGetValue("avatar_url");
|
||||
return authUser;
|
||||
}
|
||||
|
||||
public static string TryGetValue(this JsonElement.ObjectEnumerator target, string propertyName)
|
||||
{
|
||||
return target.FirstOrDefault<JsonProperty>((Func<JsonProperty, bool>)(t => t.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase))).Value.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ using ThingsGateway.NewLife;
|
||||
using ThingsGateway.NewLife.Caching;
|
||||
using ThingsGateway.NewLife.Threading;
|
||||
using ThingsGateway.Schedule;
|
||||
using ThingsGateway.SqlSugar;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
@@ -60,7 +61,7 @@ public class HardwareJob : IJob, IHardwareJob
|
||||
var historyHardwareInfos = MemoryCache.Get<List<HistoryHardwareInfo>>(CacheKey);
|
||||
if (historyHardwareInfos == null)
|
||||
{
|
||||
using var db = DbContext.Db.GetConnectionScopeWithAttr<HistoryHardwareInfo>().CopyNew();
|
||||
using var db = _db.CopyNew();
|
||||
historyHardwareInfos = await db.Queryable<HistoryHardwareInfo>().Where(a => a.Date > DateTime.Now.AddDays(-3)).ToListAsync().ConfigureAwait(false);
|
||||
|
||||
MemoryCache.Set(CacheKey, historyHardwareInfos);
|
||||
@@ -70,6 +71,7 @@ public class HardwareJob : IJob, IHardwareJob
|
||||
|
||||
private bool error = false;
|
||||
private DateTime hisInsertTime = default;
|
||||
private SqlSugarClient _db = DbContext.Db.GetConnectionScopeWithAttr<HistoryHardwareInfo>().CopyNew();
|
||||
|
||||
public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
|
||||
{
|
||||
@@ -121,7 +123,6 @@ public class HardwareJob : IJob, IHardwareJob
|
||||
if (DateTime.Now > hisInsertTime.Add(TimeSpan.FromMilliseconds(HardwareInfoOptions.HistoryInterval)))
|
||||
{
|
||||
hisInsertTime = DateTime.Now;
|
||||
using var db = DbContext.Db.GetConnectionScopeWithAttr<HistoryHardwareInfo>().CopyNew();
|
||||
{
|
||||
var his = new HistoryHardwareInfo()
|
||||
{
|
||||
@@ -132,12 +133,12 @@ public class HardwareJob : IJob, IHardwareJob
|
||||
CpuUsage = (HardwareInfo.MachineInfo.CpuRate * 100).ToInt(),
|
||||
Temperature = (HardwareInfo.MachineInfo.Temperature).ToInt(),
|
||||
};
|
||||
await db.Insertable(his).ExecuteCommandAsync(stoppingToken).ConfigureAwait(false);
|
||||
await _db.Insertable(his).ExecuteCommandAsync(stoppingToken).ConfigureAwait(false);
|
||||
MemoryCache.Remove(CacheKey);
|
||||
}
|
||||
var sevenDaysAgo = TimerX.Now.AddDays(-HardwareInfoOptions.DaysAgo);
|
||||
//删除特定信息
|
||||
var result = await db.Deleteable<HistoryHardwareInfo>(a => a.Date <= sevenDaysAgo).ExecuteCommandAsync(stoppingToken).ConfigureAwait(false);
|
||||
var result = await _db.Deleteable<HistoryHardwareInfo>(a => a.Date <= sevenDaysAgo).ExecuteCommandAsync(stoppingToken).ConfigureAwait(false);
|
||||
if (result > 0)
|
||||
{
|
||||
MemoryCache.Remove(CacheKey);
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
|
||||
using ThingsGateway.Extension;
|
||||
|
||||
@@ -80,6 +76,7 @@ public class AdminOAuthHandler<TOptions>(
|
||||
AuthenticationProperties properties,
|
||||
OAuthTokenResponse tokens)
|
||||
{
|
||||
Backchannel.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokens.AccessToken);
|
||||
properties.RedirectUri = Options.HomePath;
|
||||
properties.IsPersistent = true;
|
||||
var appConfig = await configService.GetAppConfigAsync().ConfigureAwait(false);
|
||||
@@ -90,7 +87,7 @@ public class AdminOAuthHandler<TOptions>(
|
||||
properties.ExpiresUtc = TimeProvider.System.GetUtcNow().AddSeconds(result);
|
||||
expire = (int)(result / 60.0);
|
||||
}
|
||||
var user = await HandleUserInfoAsync(tokens).ConfigureAwait(false);
|
||||
var user = await Options.HandleUserInfoAsync(Context, tokens).ConfigureAwait(false);
|
||||
|
||||
var loginEvent = await GetLogin(expire).ConfigureAwait(false);
|
||||
await UpdateUser(loginEvent).ConfigureAwait(false);
|
||||
@@ -148,43 +145,8 @@ public class AdminOAuthHandler<TOptions>(
|
||||
}
|
||||
|
||||
|
||||
/// <summary>处理用户信息方法</summary>
|
||||
protected virtual async Task<JsonElement> HandleUserInfoAsync(OAuthTokenResponse tokens)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, BuildUserInfoUrl(tokens));
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
var response = await Backchannel.SendAsync(request, Context.RequestAborted).ConfigureAwait(false);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return JsonDocument.Parse(content).RootElement;
|
||||
}
|
||||
|
||||
throw new OAuthTokenException($"OAuth user info endpoint failure: {await Display(response).ConfigureAwait(false)}");
|
||||
}
|
||||
|
||||
/// <summary>生成用户信息请求地址方法</summary>
|
||||
protected virtual string BuildUserInfoUrl(OAuthTokenResponse tokens)
|
||||
{
|
||||
return QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary<string, string>
|
||||
{
|
||||
{ "access_token", tokens.AccessToken }
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>生成错误信息方法</summary>
|
||||
protected static async Task<string> Display(HttpResponseMessage response)
|
||||
{
|
||||
var output = new StringBuilder();
|
||||
output.Append($"Status: {response.StatusCode}; ");
|
||||
output.Append($"Headers: {response.Headers}; ");
|
||||
output.Append($"Body: {await response.Content.ReadAsStringAsync().ConfigureAwait(false)};");
|
||||
|
||||
return output.ToString();
|
||||
}
|
||||
|
||||
private async Task<LoginEvent> GetLogin(int expire)
|
||||
{
|
||||
@@ -0,0 +1,87 @@
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
/// <summary>OAuthOptions 配置类</summary>
|
||||
public abstract class AdminOAuthOptions : OAuthOptions
|
||||
{
|
||||
/// <summary>默认构造函数</summary>
|
||||
protected AdminOAuthOptions()
|
||||
{
|
||||
ConfigureClaims();
|
||||
this.Events.OnRemoteFailure = context =>
|
||||
{
|
||||
var redirectUri = string.IsNullOrEmpty(HomePath) ? "/" : HomePath;
|
||||
context.Response.Redirect(redirectUri);
|
||||
context.HandleResponse();
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
Backchannel = new HttpClient(new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator // 若测试用
|
||||
});
|
||||
Backchannel.DefaultRequestHeaders.UserAgent.Add(
|
||||
new ProductInfoHeaderValue("ThingsGateway", "1.0"));
|
||||
}
|
||||
|
||||
/// <summary>配置 Claims 映射</summary>
|
||||
protected virtual void ConfigureClaims()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual string GetName(JsonElement element)
|
||||
{
|
||||
JsonElement.ObjectEnumerator target = element.EnumerateObject();
|
||||
return target.TryGetValue("name");
|
||||
}
|
||||
|
||||
/// <summary>获得/设置 登陆后首页</summary>
|
||||
public string HomePath { get; set; } = "/";
|
||||
|
||||
|
||||
|
||||
/// <summary>处理用户信息方法</summary>
|
||||
public virtual async Task<JsonElement> HandleUserInfoAsync(HttpContext context, OAuthTokenResponse tokens)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, BuildUserInfoUrl(tokens));
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
var response = await Backchannel.SendAsync(request, context.RequestAborted).ConfigureAwait(false);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return JsonDocument.Parse(content).RootElement;
|
||||
}
|
||||
|
||||
throw new OAuthTokenException($"OAuth user info endpoint failure: {await Display(response).ConfigureAwait(false)}");
|
||||
}
|
||||
|
||||
/// <summary>生成用户信息请求地址方法</summary>
|
||||
protected virtual string BuildUserInfoUrl(OAuthTokenResponse tokens)
|
||||
{
|
||||
return QueryHelpers.AddQueryString(UserInformationEndpoint, new Dictionary<string, string>
|
||||
{
|
||||
{ "access_token", tokens.AccessToken }
|
||||
});
|
||||
}
|
||||
/// <summary>生成错误信息方法</summary>
|
||||
protected async Task<string> Display(HttpResponseMessage response)
|
||||
{
|
||||
var output = new StringBuilder();
|
||||
output.Append($"Status: {response.StatusCode}; ");
|
||||
output.Append($"Headers: {response.Headers}; ");
|
||||
output.Append($"Body: {await response.Content.ReadAsStringAsync().ConfigureAwait(false)};");
|
||||
|
||||
return output.ToString();
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,20 @@ using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using ThingsGateway.NewLife.Log;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
public class GiteeOAuthOptions : AdminOAuthOptions
|
||||
{
|
||||
|
||||
INoticeService _noticeService;
|
||||
IVerificatInfoService _verificatInfoService;
|
||||
public GiteeOAuthOptions() : base()
|
||||
{
|
||||
_noticeService = App.GetService<INoticeService>();
|
||||
_verificatInfoService = App.GetService<IVerificatInfoService>();
|
||||
this.SignInScheme = ClaimConst.Scheme;
|
||||
this.AuthorizationEndpoint = "https://gitee.com/oauth/authorize";
|
||||
this.TokenEndpoint = "https://gitee.com/oauth/token";
|
||||
@@ -29,11 +33,14 @@ public class GiteeOAuthOptions : AdminOAuthOptions
|
||||
|
||||
Events.OnRedirectToAuthorizationEndpoint = context =>
|
||||
{
|
||||
//context.RedirectUri = context.RedirectUri.Replace("http%3A%2F%2F", "https%3A%2F%2F"); // 强制替换
|
||||
context.Response.Redirect(context.RedirectUri);
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
Events.OnRemoteFailure = context =>
|
||||
{
|
||||
XTrace.WriteException(context.Failure);
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>刷新 Token 方法</summary>
|
||||
@@ -60,16 +67,7 @@ public class GiteeOAuthOptions : AdminOAuthOptions
|
||||
return OAuthTokenResponse.Failed(new OAuthTokenException($"OAuth token endpoint failure: {await Display(response).ConfigureAwait(false)}"));
|
||||
}
|
||||
|
||||
/// <summary>生成错误信息方法</summary>
|
||||
protected static async Task<string> Display(HttpResponseMessage response)
|
||||
{
|
||||
var output = new StringBuilder();
|
||||
output.Append($"Status: {response.StatusCode}; ");
|
||||
output.Append($"Headers: {response.Headers}; ");
|
||||
output.Append($"Body: {await response.Content.ReadAsStringAsync().ConfigureAwait(false)};");
|
||||
|
||||
return output.ToString();
|
||||
}
|
||||
|
||||
public override string GetName(JsonElement element)
|
||||
{
|
||||
@@ -77,7 +75,7 @@ public class GiteeOAuthOptions : AdminOAuthOptions
|
||||
return target.TryGetValue("name");
|
||||
}
|
||||
|
||||
private static async Task HandlerGiteeStarredUrl(OAuthCreatingTicketContext context, string repoFullName = "ThingsGateway/ThingsGateway")
|
||||
private async Task HandlerGiteeStarredUrl(OAuthCreatingTicketContext context, string repoFullName = "ThingsGateway/ThingsGateway")
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(context.AccessToken))
|
||||
throw new InvalidOperationException("Access token is missing.");
|
||||
@@ -89,7 +87,7 @@ public class GiteeOAuthOptions : AdminOAuthOptions
|
||||
{ "access_token", context.AccessToken }
|
||||
};
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Put, QueryHelpers.AddQueryString(uri, queryString))
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, QueryHelpers.AddQueryString(uri, queryString))
|
||||
{
|
||||
Headers = { Accept = { new MediaTypeWithQualityHeaderValue("application/json") } }
|
||||
};
|
||||
@@ -99,7 +97,17 @@ public class GiteeOAuthOptions : AdminOAuthOptions
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
throw new Exception($"Failed to star repository: {response.StatusCode}, {content}");
|
||||
|
||||
var id = context.Identity.Claims.FirstOrDefault(a => a.Type == ClaimConst.VerificatId).Value;
|
||||
|
||||
var verificatInfoIds = _verificatInfoService.GetOne(id.ToLong());
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await _noticeService.NavigationMesage(verificatInfoIds.ClientIds, "https://gitee.com/ThingsGateway/ThingsGateway", "创作不易,如有帮助请star仓库").ConfigureAwait(false);
|
||||
});
|
||||
//throw new Exception($"Failed to star repository: {response.StatusCode}, {content}");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.Json;
|
||||
|
||||
using ThingsGateway.NewLife.Log;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
public class GitHubOAuthOptions : AdminOAuthOptions
|
||||
{
|
||||
INoticeService _noticeService;
|
||||
IVerificatInfoService _verificatInfoService;
|
||||
public GitHubOAuthOptions() : base()
|
||||
{
|
||||
_noticeService = App.GetService<INoticeService>();
|
||||
_verificatInfoService = App.GetService<IVerificatInfoService>();
|
||||
SignInScheme = ClaimConst.Scheme;
|
||||
AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
|
||||
TokenEndpoint = "https://github.com/login/oauth/access_token";
|
||||
UserInformationEndpoint = "https://api.github.com/user";
|
||||
HomePath = "/";
|
||||
CallbackPath = "/signin-github";
|
||||
|
||||
Scope.Add("read:user");
|
||||
Scope.Add("public_repo"); // 需要用于 Star 仓库
|
||||
|
||||
Events.OnCreatingTicket = async context =>
|
||||
{
|
||||
await HandleGitHubStarAsync(context).ConfigureAwait(false);
|
||||
};
|
||||
|
||||
Events.OnRedirectToAuthorizationEndpoint = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri);
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
Events.OnRemoteFailure = context =>
|
||||
{
|
||||
XTrace.WriteException(context.Failure);
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
}
|
||||
|
||||
protected override void ConfigureClaims()
|
||||
{
|
||||
ClaimActions.MapJsonKey(ClaimConst.AvatarUrl, "avatar_url");
|
||||
ClaimActions.MapJsonKey(ClaimConst.Account, "login");
|
||||
|
||||
base.ConfigureClaims();
|
||||
}
|
||||
|
||||
public override string GetName(JsonElement element)
|
||||
{
|
||||
if (element.TryGetProperty("login", out var loginProp))
|
||||
{
|
||||
return loginProp.GetString() ?? string.Empty;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private async Task HandleGitHubStarAsync(OAuthCreatingTicketContext context, string repoFullName = "ThingsGateway/ThingsGateway")
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(context.AccessToken))
|
||||
throw new InvalidOperationException("Access token is missing.");
|
||||
|
||||
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Put, $"https://api.github.com/user/starred/{repoFullName}")
|
||||
{
|
||||
Headers =
|
||||
{
|
||||
Accept = { new MediaTypeWithQualityHeaderValue("application/vnd.github+json") },
|
||||
Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken),
|
||||
},
|
||||
Content = new StringContent(string.Empty) // GitHub Star 接口需要空内容
|
||||
};
|
||||
request.Headers.UserAgent.Add(new ProductInfoHeaderValue("ThingsGateway", "1.0")); // GitHub API 要求 User-Agent
|
||||
|
||||
var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
var id = context.Identity.Claims.FirstOrDefault(a => a.Type == ClaimConst.VerificatId).Value;
|
||||
|
||||
var verificatInfoIds = _verificatInfoService.GetOne(id.ToLong());
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await _noticeService.NavigationMesage(verificatInfoIds.ClientIds, "https://github.com/ThingsGateway/ThingsGateway", "创作不易,如有帮助请star仓库").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>处理用户信息方法</summary>
|
||||
public override async Task<JsonElement> HandleUserInfoAsync(HttpContext context, OAuthTokenResponse tokens)
|
||||
{
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, UserInformationEndpoint);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json"));
|
||||
request.Headers.UserAgent.Add(new ProductInfoHeaderValue("ThingsGateway", "1.0")); // GitHub API 要求 User-Agent
|
||||
var response = await Backchannel.SendAsync(request, context.RequestAborted).ConfigureAwait(false);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return JsonDocument.Parse(content).RootElement;
|
||||
}
|
||||
|
||||
throw new OAuthTokenException($"OAuth user info endpoint failure: {await Display(response).ConfigureAwait(false)}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
public class GithubOAuthSettings : GiteeOAuthSettings
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
public static class OAuthUserExtensions
|
||||
{
|
||||
public static string TryGetValue(this JsonElement.ObjectEnumerator target, string propertyName)
|
||||
{
|
||||
return target.FirstOrDefault<JsonProperty>((Func<JsonProperty, bool>)(t => t.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase))).Value.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public class SysRelationSeedData : ISqlSugarEntitySeedData<SysRelation>
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<SysRelation> SeedData()
|
||||
{
|
||||
var db = DbContext.Db.GetConnectionScopeWithAttr<SysRelation>().CopyNew();
|
||||
using var db = DbContext.Db.GetConnectionScopeWithAttr<SysRelation>().CopyNew();
|
||||
if (db.Queryable<SysRelation>().Any(a => a.ObjectId == RoleConst.SuperAdminId))
|
||||
return Enumerable.Empty<SysRelation>();
|
||||
var data = SeedDataUtil.GetSeedData<SysRelation>(PathExtensions.CombinePathWithOs("SeedData", "Admin", "seed_sys_relation.json"));
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
@<div>
|
||||
<span class="mx-3">@item.ConfirmMessage</span>
|
||||
|
||||
<Button Text=@Localizers["Jump"] Color="Color.Link" OnClick="()=>NavigationManager.NavigateTo(item.Uri)"></Button>
|
||||
<a href=@item.Uri target="_blank">
|
||||
@item.Uri
|
||||
</a>
|
||||
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</PopConfirmButton>
|
||||
<PopConfirmButton Color=Color.Warning IsDisabled="SelectedRows.Count!=1||!AuthorizeButton(AdminOperConst.Edit)" Text=@OperDescLocalizer["ChangeParentResource"] Icon="fa fa-copy" OnConfirm="OnChangeParent">
|
||||
<BodyTemplate>
|
||||
<div class="min-height-500 overflow-y-auto">
|
||||
<div class="overflow-y-auto" style="height:500px">
|
||||
<TreeView Items="MenuTreeItems" IsVirtualize="true" OnTreeItemClick="a=>{ChangeParentId=a.Value.Id;return Task.CompletedTask;}" />
|
||||
</div>
|
||||
</BodyTemplate>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
<!--动态适用GC-->
|
||||
<GarbageCollectionAdaptationMode>1</GarbageCollectionAdaptationMode>
|
||||
<CETCompat>false</CETCompat>
|
||||
<!--使用自托管线程池-->
|
||||
<!--<UseWindowsThreadPool>false</UseWindowsThreadPool> -->
|
||||
|
||||
|
||||
@@ -124,16 +124,8 @@ public class SugarAopService : ISugarAopService
|
||||
//执行时间超过1秒
|
||||
if (db.Ado.SqlExecutionTime.TotalSeconds > 1)
|
||||
{
|
||||
//代码CS文件名
|
||||
var fileName = db.Ado.SqlStackTrace.FirstFileName;
|
||||
//代码行数
|
||||
var fileLine = db.Ado.SqlStackTrace.FirstLine;
|
||||
//方法名
|
||||
var FirstMethodName = db.Ado.SqlStackTrace.FirstMethodName;
|
||||
|
||||
DbContext.WriteLog($"{fileName}-{FirstMethodName}-{fileLine} 执行时间超过1秒");
|
||||
DbContext.WriteLog($"SQL执行时间超过1秒");
|
||||
DbContext.WriteLogWithSql(UtilMethods.GetNativeSql(sql, pars));
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using ThingsGateway.SqlSugar;
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
<PackageReference Include="MiniProfiler.AspNetCore.Mvc" Version="4.5.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
||||
|
||||
@@ -1160,7 +1160,7 @@ public class MachineInfo
|
||||
public static String GetInfo(String path, String property, String? nameSpace = null)
|
||||
{
|
||||
// Linux Mono不支持WMI
|
||||
if (Runtime.Mono) return "";
|
||||
if (Runtime.Mono) return string.Empty;
|
||||
|
||||
var bbs = new List<String>();
|
||||
try
|
||||
@@ -1181,7 +1181,7 @@ public class MachineInfo
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (XTrace.Log.Level <= LogLevel.Debug) XTrace.WriteLine("WMI.GetInfo({0})失败!{1}", path, ex.Message);
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
bbs.Sort();
|
||||
|
||||
@@ -854,13 +854,13 @@ public static class IOHelper
|
||||
/// <returns></returns>
|
||||
public static String ToHex(this Byte[]? data, Int32 offset = 0, Int32 count = -1)
|
||||
{
|
||||
if (data == null || data.Length <= 0) return "";
|
||||
if (data == null || data.Length <= 0) return string.Empty;
|
||||
|
||||
if (count < 0)
|
||||
count = data.Length - offset;
|
||||
else if (offset + count > data.Length)
|
||||
count = data.Length - offset;
|
||||
if (count == 0) return "";
|
||||
if (count == 0) return string.Empty;
|
||||
|
||||
//return BitConverter.ToString(data).Replace("-", null);
|
||||
// 上面的方法要替换-,效率太低
|
||||
@@ -883,7 +883,7 @@ public static class IOHelper
|
||||
/// <returns></returns>
|
||||
public static String ToHex(this Byte[]? data, String? separate, Int32 groupSize = 0, Int32 maxLength = -1)
|
||||
{
|
||||
if (data == null || data.Length <= 0) return "";
|
||||
if (data == null || data.Length <= 0) return string.Empty;
|
||||
|
||||
if (groupSize < 0) groupSize = 0;
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using ThingsGateway.NewLife;
|
||||
|
||||
@@ -201,9 +201,9 @@ namespace ThingsGateway.SqlSugar
|
||||
try
|
||||
{
|
||||
|
||||
if (this.Context.CurrentConnectionConfig?.MoreSettings?.IsNoReadXmlDescription == true)
|
||||
if (this.Context.CurrentConnectionConfig?.MoreSettings?.IsNoReadXmlDescription ?? true == true)
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
if (entityType.Assembly.IsDynamic && entityType.Assembly.FullName.StartsWith("Dynamic"))
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
public int DefaultCacheDurationInSeconds { get; set; }
|
||||
public bool? TableEnumIsString { get; set; }
|
||||
public DateTime? DbMinDate { get; set; } = DateTime.MinValue.Date.AddYears(1900 - 1);
|
||||
public bool IsNoReadXmlDescription { get; set; }
|
||||
public bool IsNoReadXmlDescription { get; set; } = true;
|
||||
public bool SqlServerCodeFirstNvarchar { get; set; }
|
||||
public bool OracleCodeFirstNvarchar2 { get; set; }
|
||||
public bool SqliteCodeFirstEnableDefaultValue { get; set; }
|
||||
|
||||
@@ -501,7 +501,7 @@ namespace ThingsGateway.SqlSugar
|
||||
{
|
||||
return GetFirstTypeNameFromExpression(methodCall.Arguments.FirstOrDefault());
|
||||
}
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string GetMethodName(Expression expression)
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace ThingsGateway.SqlSugar
|
||||
|
||||
public string GetMemberName(MemberExpression memberExpression)
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private void ExtMapper(MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2, MapperExpressionInfo selectInfo)
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace ThingsGateway.SqlSugar
|
||||
var isWhere = Convert.ToBoolean(value);
|
||||
if (!Convert.ToBoolean(isWhere))
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
var argExp = exp.Arguments[1];
|
||||
var copyContext = this.Context;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ThingsGateway.SqlSugar
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ WHERE table_name = '" + tableName + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace ThingsGateway.SqlSugar
|
||||
public string DataTableToCsvString(DataTable table)
|
||||
{
|
||||
if (table.Rows.Count == 0)
|
||||
return "";
|
||||
return string.Empty;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
DataColumn colum;
|
||||
foreach (DataRow row in table.Rows)
|
||||
|
||||
@@ -262,7 +262,7 @@ namespace ThingsGateway.SqlSugar
|
||||
{
|
||||
get
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace ThingsGateway.SqlSugar
|
||||
{
|
||||
get
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
protected override string AddColumnToTableSql
|
||||
|
||||
@@ -92,12 +92,12 @@ namespace ThingsGateway.SqlSugar
|
||||
public static string ObjToString(this object thisValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString().Trim();
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
public static string ObjToStringNoTrim(this object thisValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString();
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
public static string ObjToStringNew(this object thisValue)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ namespace ThingsGateway.SqlSugar
|
||||
return Convert.ToDateTime(thisValue.ToString()).ToString("yyyy-MM-dd");
|
||||
}
|
||||
if (thisValue != null) return thisValue.ToString().Trim();
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string ObjToString(this object thisValue, string errorValue)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
public static string ObjToString(this object thisValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString().Trim();
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string ObjToString(this object thisValue, string errorValue)
|
||||
|
||||
@@ -893,42 +893,25 @@ namespace ThingsGateway.SqlSugar
|
||||
return Guid.NewGuid() + "";
|
||||
}
|
||||
}
|
||||
static Type IAsyncStateMachineType = typeof(IAsyncStateMachine);
|
||||
|
||||
public static bool IsAsyncMethod(MethodBase method)
|
||||
{
|
||||
if (method == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (method.DeclaringType != null)
|
||||
{
|
||||
if (method.DeclaringType.GetInterfaces().Contains(typeof(IAsyncStateMachine)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (method == null) return false;
|
||||
|
||||
if (method.GetCustomAttribute<AsyncStateMachineAttribute>() != null)
|
||||
return true;
|
||||
|
||||
if (method.DeclaringType?.GetInterfaces().Contains(IAsyncStateMachineType) == true)
|
||||
return true;
|
||||
|
||||
// 补救方案:有些 async 方法是动态生成的,名字惯例判断
|
||||
var name = method.Name;
|
||||
if (name.Contains("OutputAsyncCausalityEvents"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (name.Contains("OutputWaitEtwEvents"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (name.Contains("ExecuteAsync"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//if (method?.DeclaringType?.FullName?.Contains("Furion.InternalApp")==true)
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
Type attType = typeof(AsyncStateMachineAttribute);
|
||||
var attrib = (AsyncStateMachineAttribute)method.GetCustomAttribute(attType);
|
||||
return (attrib != null);
|
||||
return name.EndsWith("ExecuteAsync") || name.Contains("OutputAsyncCausalityEvents") || name.Contains("OutputWaitEtwEvents");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static StackTraceInfo GetStackTrace()
|
||||
{
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace ThingsGateway.SqlSugar.TDengine
|
||||
{
|
||||
get
|
||||
{
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
public static string ObjToStringNoTrim(this object thisValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString();
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
public static string ToLower(this string value, bool isLower)
|
||||
{
|
||||
@@ -78,7 +78,7 @@
|
||||
public static string ObjToString(this object thisValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString().Trim();
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string ObjToString(this object thisValue, string errorValue)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.7.54</PluginVersion>
|
||||
<ProPluginVersion>10.7.54</ProPluginVersion>
|
||||
<PluginVersion>10.7.58</PluginVersion>
|
||||
<ProPluginVersion>10.7.58</ProPluginVersion>
|
||||
<AuthenticationVersion>2.6.0</AuthenticationVersion>
|
||||
<NET8Version>8.0.17</NET8Version>
|
||||
<NET9Version>9.0.6</NET9Version>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Behaviors;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Behaviors;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Controls;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Events;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Extensions;
|
||||
|
||||
@@ -23,6 +23,12 @@ public abstract class BusinessBaseWithCacheAlarmModel<VarModel, DevModel, AlarmM
|
||||
protected ConcurrentQueue<CacheDBItem<AlarmModel>> _memoryAlarmModelQueue = new();
|
||||
|
||||
private volatile bool LocalDBCacheAlarmModelInited;
|
||||
private CacheDB DBCacheAlarm;
|
||||
protected internal override Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken)
|
||||
{
|
||||
DBCacheAlarm = LocalDBCacheAlarmModel();
|
||||
return base.InitChannelAsync(channel, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入缓存
|
||||
@@ -161,10 +167,8 @@ public abstract class BusinessBaseWithCacheAlarmModel<VarModel, DevModel, AlarmM
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
using var cache = LocalDBCacheAlarmModel();
|
||||
|
||||
//循环获取,固定读最大行数量,执行完成需删除行
|
||||
var varList = await cache.DBProvider.Queryable<CacheDBItem<AlarmModel>>().Take(_businessPropertyWithCache.SplitSize).ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||
var varList = await DBCacheAlarm.DBProvider.Queryable<CacheDBItem<AlarmModel>>().Take(_businessPropertyWithCache.SplitSize).ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (varList.Count > 0)
|
||||
{
|
||||
try
|
||||
@@ -175,7 +179,7 @@ public abstract class BusinessBaseWithCacheAlarmModel<VarModel, DevModel, AlarmM
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
//删除缓存
|
||||
await cache.DBProvider.Deleteable<CacheDBItem<AlarmModel>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
await DBCacheAlarm.DBProvider.Deleteable<CacheDBItem<AlarmModel>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@@ -24,6 +24,14 @@ public abstract class BusinessBaseWithCacheDeviceModel<VarModel, DevModel> : Bus
|
||||
|
||||
private volatile bool LocalDBCacheDevModelInited;
|
||||
|
||||
private CacheDB DBCacheDev;
|
||||
protected internal override Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken)
|
||||
{
|
||||
DBCacheDev = LocalDBCacheDevModel();
|
||||
return base.InitChannelAsync(channel, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 入缓存
|
||||
/// </summary>
|
||||
@@ -159,10 +167,9 @@ public abstract class BusinessBaseWithCacheDeviceModel<VarModel, DevModel> : Bus
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
using var cache = LocalDBCacheDevModel();
|
||||
|
||||
//循环获取
|
||||
var varList = await cache.DBProvider.Queryable<CacheDBItem<DevModel>>().Take(_businessPropertyWithCache.SplitSize).ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||
var varList = await DBCacheDev.DBProvider.Queryable<CacheDBItem<DevModel>>().Take(_businessPropertyWithCache.SplitSize).ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (varList.Count > 0)
|
||||
{
|
||||
try
|
||||
@@ -173,7 +180,7 @@ public abstract class BusinessBaseWithCacheDeviceModel<VarModel, DevModel> : Bus
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
//删除缓存
|
||||
await cache.DBProvider.Deleteable<CacheDBItem<DevModel>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
await DBCacheDev.DBProvider.Deleteable<CacheDBItem<DevModel>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@@ -25,6 +25,16 @@ public abstract class BusinessBaseWithCacheVariableModel<VarModel> : BusinessBas
|
||||
protected volatile bool success = true;
|
||||
private volatile bool LocalDBCacheVarModelInited;
|
||||
private volatile bool LocalDBCacheVarModelsInited;
|
||||
private CacheDB DBCacheVar;
|
||||
private CacheDB DBCacheVars;
|
||||
protected internal override Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken)
|
||||
{
|
||||
DBCacheVar = LocalDBCacheVarModel();
|
||||
DBCacheVars = LocalDBCacheVarModels();
|
||||
return base.InitChannelAsync(channel, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
protected sealed override BusinessPropertyBase _businessPropertyBase => _businessPropertyWithCache;
|
||||
|
||||
protected abstract BusinessPropertyWithCache _businessPropertyWithCache { get; }
|
||||
@@ -264,8 +274,8 @@ public abstract class BusinessBaseWithCacheVariableModel<VarModel> : BusinessBas
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
//循环获取
|
||||
using var cache = LocalDBCacheVarModel();
|
||||
var varList = await cache.DBProvider.Queryable<CacheDBItem<VarModel>>().Take(_businessPropertyWithCache.SplitSize).ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var varList = await DBCacheVar.DBProvider.Queryable<CacheDBItem<VarModel>>().Take(_businessPropertyWithCache.SplitSize).ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (varList.Count > 0)
|
||||
{
|
||||
try
|
||||
@@ -276,7 +286,7 @@ public abstract class BusinessBaseWithCacheVariableModel<VarModel> : BusinessBas
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
//删除缓存
|
||||
await cache.DBProvider.Deleteable<CacheDBItem<VarModel>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
await DBCacheVar.DBProvider.Deleteable<CacheDBItem<VarModel>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -325,8 +335,8 @@ public abstract class BusinessBaseWithCacheVariableModel<VarModel> : BusinessBas
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
//循环获取
|
||||
using var cache = LocalDBCacheVarModels();
|
||||
var varList = await cache.DBProvider.Queryable<CacheDBItem<List<VarModel>>>().FirstAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var varList = await DBCacheVars.DBProvider.Queryable<CacheDBItem<List<VarModel>>>().FirstAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (varList?.Value?.Count > 0)
|
||||
{
|
||||
try
|
||||
@@ -337,7 +347,7 @@ public abstract class BusinessBaseWithCacheVariableModel<VarModel> : BusinessBas
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
//删除缓存
|
||||
await cache.DBProvider.Deleteable<CacheDBItem<List<VarModel>>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
await DBCacheVars.DBProvider.Deleteable<CacheDBItem<List<VarModel>>>(varList).ExecuteCommandAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,7 @@ using System.Collections.Concurrent;
|
||||
using ThingsGateway.Extension;
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
using ThingsGateway.SqlSugar;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -249,12 +250,13 @@ internal sealed class RpcService : IRpcService
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private SqlSugarClient _db = DbContext.Db.GetConnectionScopeWithAttr<RpcLog>().CopyNew(); // 创建一个新的数据库上下文实例
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行RPC日志插入操作的方法。
|
||||
/// </summary>
|
||||
private async Task RpcLogInsertAsync()
|
||||
{
|
||||
var db = DbContext.Db.GetConnectionScopeWithAttr<RpcLog>().CopyNew(); // 创建一个新的数据库上下文实例
|
||||
var appLifetime = App.RootServices!.GetService<IHostApplicationLifetime>()!;
|
||||
while (!appLifetime.ApplicationStopping.IsCancellationRequested)
|
||||
{
|
||||
@@ -264,7 +266,7 @@ internal sealed class RpcService : IRpcService
|
||||
if (data.Count > 0)
|
||||
{
|
||||
// 将数据插入到数据库中
|
||||
await db.InsertableWithAttr(data).ExecuteCommandAsync(appLifetime.ApplicationStopping).ConfigureAwait(false);
|
||||
await _db.InsertableWithAttr(data).ExecuteCommandAsync(appLifetime.ApplicationStopping).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -4,7 +4,6 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using ThingsGateway.SqlSugar;
|
||||
|
||||
@@ -19,8 +19,6 @@ using ThingsGateway.Blazor.Diagrams.Core.Anchors;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
|
||||
using static Dm.net.buffer.ByteArrayBuffer;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
public static class RuleHelpers
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.Gateway.Application.Extensions;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
public abstract class NumberNode : PlaceholderNode
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
public abstract class TextNode : PlaceholderNode
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.NewLife;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
public abstract class VariableNode : TextNode
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using ThingsGateway.Blazor.Diagrams.Core;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Controls.Default;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models.Base;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Options;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
@@ -16,7 +16,6 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
using ThingsGateway.Blazor.Diagrams.Core;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -12,9 +12,7 @@ using BootstrapBlazor.Components;
|
||||
|
||||
using System.Data;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.SqlSugar;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using Mapster;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -18,7 +17,6 @@ using System.Reflection;
|
||||
|
||||
using ThingsGateway.Authentication;
|
||||
using ThingsGateway.Management;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.SqlSugar;
|
||||
using ThingsGateway.Upgrade;
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Admin.Razor;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class ChannelEditComponent
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class ChannelRuntimeInfo
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class ChannelRuntimeInfo1 : IDisposable
|
||||
|
||||
@@ -14,7 +14,6 @@ using Microsoft.AspNetCore.Components.Forms;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
|
||||
@@ -14,7 +14,6 @@ using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
using ThingsGateway.Admin.Razor;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
using ThingsGateway.SqlSugar;
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
public enum ChannelDevicePluginTypeEnum
|
||||
{
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class DeviceRuntimeInfo
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class DeviceRuntimeInfo1 : IDisposable
|
||||
|
||||
@@ -14,7 +14,6 @@ using Microsoft.AspNetCore.Components.Forms;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
@@ -7,26 +7,24 @@
|
||||
@namespace ThingsGateway.Gateway.Razor
|
||||
|
||||
|
||||
<ValidateForm Model="Model.Value"
|
||||
@key=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")
|
||||
<ValidateForm Model="Model.Value"
|
||||
@key=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")
|
||||
@ref=Model.ValidateForm
|
||||
Id=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")>
|
||||
|
||||
@ref=Model.ValidateForm
|
||||
Id=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")
|
||||
>
|
||||
|
||||
<EditorFormObject class="p-2" Items=PluginPropertyEditorItems IsDisplay="!CanWrite" AutoGenerateAllItem="false" RowType=RowType.Inline ItemsPerRow=@(CanWrite?2:3) ShowLabelTooltip=true LabelWidth=@(CanWrite?240:120) Model="Model.Value" ShowLabel="true" @key=@($"DeviceEditEditorFormObject{Id}{Model.Value.GetType().TypeHandle.Value}")>
|
||||
<EditorFormObject class="p-2" Items=PluginPropertyEditorItems IsDisplay="!CanWrite" AutoGenerateAllItem="false" RowType=RowType.Inline ItemsPerRow=@(CanWrite ? 2 : 3) ShowLabelTooltip=true LabelWidth=@(CanWrite ? 240 : 120) Model="Model.Value" ShowLabel="true" @key=@($"DeviceEditEditorFormObject{Id}{Model.Value.GetType().TypeHandle.Value}")>
|
||||
|
||||
<FieldItems>
|
||||
@if (Model.Value is BusinessPropertyWithCacheIntervalScript businessProperty)
|
||||
{
|
||||
<EditorItem FieldExpression=@(()=>context) Field=@(context)>
|
||||
<EditorItem FieldExpression=@(() => context) Field=@(context)>
|
||||
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-md-12 min-height-500">
|
||||
<BootstrapLabel Value=@PropertyComponentLocalizer["BigTextScriptDeviceModel"] ShowLabelTooltip="true" />
|
||||
<CodeEditor ShowLineNo @bind-Value=@businessProperty.BigTextScriptDeviceModel Language="csharp" Theme="vs-dark" IsReadonly=@(!CanWrite) />
|
||||
<div class="ms-2 d-flex justify-content-center align-items-center">
|
||||
<Button IsDisabled=@(!CanWrite) OnClick="()=>CheckScript(businessProperty,nameof(businessProperty.BigTextScriptDeviceModel))">
|
||||
<Button IsDisabled=@(!CanWrite) OnClick=@(() => CheckScript(businessProperty, nameof(businessProperty.BigTextScriptDeviceModel), Localizer["check"], this, DialogService))>
|
||||
@Localizer["Check"]
|
||||
</Button>
|
||||
</div>
|
||||
@@ -36,7 +34,7 @@ Id=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")
|
||||
<CodeEditor IsReadonly=@(!CanWrite) ShowLineNo @bind-Value=@businessProperty.BigTextScriptVariableModel Language="csharp" Theme="vs-dark" />
|
||||
|
||||
<div class="ms-2 d-flex justify-content-center align-items-center">
|
||||
<Button IsDisabled=@(!CanWrite) OnClick="()=>CheckScript(businessProperty,nameof(businessProperty.BigTextScriptVariableModel))">
|
||||
<Button IsDisabled=@(!CanWrite) OnClick=@(() => CheckScript(businessProperty, nameof(businessProperty.BigTextScriptVariableModel), Localizer["check"], this, DialogService))>
|
||||
@Localizer["Check"]
|
||||
</Button>
|
||||
</div>
|
||||
@@ -46,7 +44,7 @@ Id=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")
|
||||
<CodeEditor IsReadonly=@(!CanWrite) ShowLineNo @bind-Value=@businessProperty.BigTextScriptAlarmModel Language="csharp" Theme="vs-dark" />
|
||||
|
||||
<div class="ms-2 d-flex justify-content-center align-items-center">
|
||||
<Button IsDisabled=@(!CanWrite) OnClick="()=>CheckScript(businessProperty,nameof(businessProperty.BigTextScriptAlarmModel))">
|
||||
<Button IsDisabled=@(!CanWrite) OnClick=@(() => CheckScript(businessProperty, nameof(businessProperty.BigTextScriptAlarmModel), Localizer["check"], this, DialogService))>
|
||||
@Localizer["Check"]
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// QQ群:605534569
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
public partial class PropertyComponent : IPropertyUIBase
|
||||
@@ -34,7 +34,7 @@ public partial class PropertyComponent : IPropertyUIBase
|
||||
[Inject]
|
||||
private IStringLocalizer<DeviceEditComponent> Localizer { get; set; }
|
||||
|
||||
private async Task CheckScript(BusinessPropertyWithCacheIntervalScript businessProperty, string pname)
|
||||
public static async Task CheckScript(BusinessPropertyWithCacheIntervalScript businessProperty, string pname, string title, object receiver, DialogService dialogService)
|
||||
{
|
||||
string script = null;
|
||||
if (pname == nameof(BusinessPropertyWithCacheIntervalScript.BigTextScriptAlarmModel))
|
||||
@@ -58,7 +58,7 @@ public partial class PropertyComponent : IPropertyUIBase
|
||||
var op = new DialogOption()
|
||||
{
|
||||
IsScrolling = true,
|
||||
Title = Localizer["Check"],
|
||||
Title = title,
|
||||
ShowFooter = false,
|
||||
ShowCloseButton = false,
|
||||
Size = Size.ExtraExtraLarge,
|
||||
@@ -67,8 +67,16 @@ public partial class PropertyComponent : IPropertyUIBase
|
||||
|
||||
op.Component = BootstrapDynamicComponent.CreateComponent<ScriptCheck>(new Dictionary<string, object?>
|
||||
{
|
||||
{nameof(ScriptCheck.Data),Array.Empty<object>() },
|
||||
{nameof(ScriptCheck.Script),script },
|
||||
{nameof(ScriptCheck.GetResult), (string input,string script)=>
|
||||
{
|
||||
var type= script == businessProperty.BigTextScriptDeviceModel?typeof(List<DeviceBasicData>):script ==businessProperty.BigTextScriptAlarmModel?typeof(List<AlarmVariable>):typeof(List<VariableBasicData>);
|
||||
|
||||
var data = (IEnumerable<object>)Newtonsoft.Json.JsonConvert.DeserializeObject(input, type);
|
||||
var value = data.GetDynamicModel(script);
|
||||
return Task.FromResult( value.ToSystemTextJsonString());
|
||||
}},
|
||||
|
||||
{nameof(ScriptCheck.OnGetDemo),()=>
|
||||
{
|
||||
return
|
||||
@@ -210,7 +218,7 @@ public partial class PropertyComponent : IPropertyUIBase
|
||||
;
|
||||
}
|
||||
},
|
||||
{nameof(ScriptCheck.ScriptChanged),EventCallback.Factory.Create<string>(this, v =>
|
||||
{nameof(ScriptCheck.ScriptChanged),EventCallback.Factory.Create<string>(receiver, v =>
|
||||
{
|
||||
if (pname == nameof(BusinessPropertyWithCacheIntervalScript.BigTextScriptAlarmModel))
|
||||
{
|
||||
@@ -229,7 +237,7 @@ public partial class PropertyComponent : IPropertyUIBase
|
||||
}) },
|
||||
|
||||
});
|
||||
await DialogService.Show(op);
|
||||
await dialogService.Show(op);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,18 +8,14 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class ScriptCheck
|
||||
{
|
||||
private string Input { get; set; }
|
||||
[Parameter, EditorRequired]
|
||||
public string Input { get; set; } = string.Empty;
|
||||
private string Output { get; set; }
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public IEnumerable<object> Data { get; set; }
|
||||
[Parameter, EditorRequired]
|
||||
public string Script { get; set; }
|
||||
[Parameter, EditorRequired]
|
||||
@@ -31,21 +27,20 @@ public partial class ScriptCheck
|
||||
await ScriptChanged.InvokeAsync(script);
|
||||
|
||||
}
|
||||
private Type type;
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Input = Data.ToSystemTextJsonString();
|
||||
type = Data.GetType();
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private void CheckScript()
|
||||
[Parameter]
|
||||
public Func<string, string, Task<string>> GetResult { get; set; }
|
||||
|
||||
private async Task CheckScript()
|
||||
{
|
||||
try
|
||||
{
|
||||
Data = (IEnumerable<object>)Newtonsoft.Json.JsonConvert.DeserializeObject(Input, type);
|
||||
var value = Data.GetDynamicModel(Script);
|
||||
Output = value.ToSystemTextJsonString();
|
||||
|
||||
if (GetResult != null)
|
||||
{
|
||||
Output = await GetResult(Input, Script).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class GatewayInfo
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class GatewayMonitorPage
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ using Microsoft.Extensions.Options;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class BackendLogPage
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class RpcLogPage
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class PluginPage
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
public partial class SavePlugin
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace ThingsGateway.Gateway.Razor
|
||||
return (await expressionNode.ExecuteAsync(new NodeInput(){Value=a==null?a:JToken.Parse(a??string.Empty) },default).ConfigureAwait(false)).JToken?.ToString();
|
||||
if(Node is IActuatorNode actuatorNode)
|
||||
return (await actuatorNode.ExecuteAsync(new NodeInput(){Value=a==null?a:JToken.Parse(a??string.Empty) },default).ConfigureAwait(false)).JToken?.ToString();
|
||||
return "";
|
||||
return string.Empty;
|
||||
}) },
|
||||
{nameof(ScriptEdit.Script),Node.Text },
|
||||
{nameof(ScriptEdit.ScriptChanged),EventCallback.Factory.Create<string>(this, v =>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Gateway.Razor;
|
||||
|
||||
[ThingsGateway.DependencyInjection.SuppressSniffer]
|
||||
|
||||
@@ -15,8 +15,7 @@ global using Microsoft.Extensions.Localization;
|
||||
|
||||
global using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
global using ThingsGateway.Gateway.Application;
|
||||
global using ThingsGateway.Razor;
|
||||
|
||||
global using ThingsGateway.Gateway.Application;
|
||||
|
||||
[assembly: SuppressMessage("Reliability", "CA2007", Justification = "<挂起>", Scope = "module")]
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Debug;
|
||||
|
||||
@@ -188,7 +188,7 @@ public struct PropertyID : ISerializable
|
||||
return $"{Code}";
|
||||
}
|
||||
|
||||
return "";
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private sealed class Names
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
@using BootstrapBlazor.Components
|
||||
@using Microsoft.Extensions.Localization
|
||||
@using ThingsGateway.Extension
|
||||
@using ThingsGateway.Foundation
|
||||
@using ThingsGateway.Admin.Application
|
||||
@using ThingsGateway.Admin.Razor
|
||||
@using ThingsGateway.Gateway.Application
|
||||
@using ThingsGateway.Plugin.SqlDB
|
||||
@namespace ThingsGateway.Plugin.DB
|
||||
|
||||
|
||||
<ValidateForm Model="Model.Value"
|
||||
@key=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")
|
||||
@ref=Model.ValidateForm
|
||||
Id=@($"DeviceEditValidateForm{Id}{Model.Value.GetType().TypeHandle.Value}")>
|
||||
|
||||
<EditorFormObject class="p-2" Items=PluginPropertyEditorItems IsDisplay="!CanWrite" AutoGenerateAllItem="false" RowType=RowType.Inline ItemsPerRow=@(CanWrite?2:3) ShowLabelTooltip=true LabelWidth=@(CanWrite?240:120) Model="Model.Value" ShowLabel="true" @key=@($"DeviceEditEditorFormObject{Id}{Model.Value.GetType().TypeHandle.Value}")>
|
||||
|
||||
<FieldItems>
|
||||
@if (Model.Value is RealDBProducerProperty businessProperty)
|
||||
{
|
||||
<EditorItem FieldExpression=@(()=>context) Field=@(context)>
|
||||
|
||||
<EditTemplate Context="value">
|
||||
<div class="col-12 col-md-12">
|
||||
<BootstrapLabel Value=@RealDBProducerPropertyLocalizer["BigTextScriptHistoryTable"] ShowLabelTooltip="true" />
|
||||
<CodeEditor @bind-Value=@businessProperty.BigTextScriptHistoryTable Language="csharp" Theme="vs-dark" />
|
||||
</div>
|
||||
|
||||
</EditTemplate>
|
||||
</EditorItem>
|
||||
}
|
||||
|
||||
</FieldItems>
|
||||
</EditorFormObject>
|
||||
</ValidateForm>
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://thingsgateway.cn/
|
||||
// QQ群:605534569
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
using ThingsGateway.Razor;
|
||||
|
||||
namespace ThingsGateway.Plugin.DB
|
||||
{
|
||||
public partial class RealDBProducerPropertyRazor : IPropertyUIBase
|
||||
{
|
||||
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public IEnumerable<IEditorItem> PluginPropertyEditorItems { get; set; }
|
||||
[Parameter, EditorRequired]
|
||||
public string Id { get; set; }
|
||||
[Parameter, EditorRequired]
|
||||
public bool CanWrite { get; set; }
|
||||
[Parameter, EditorRequired]
|
||||
public ModelValueValidateForm Model { get; set; }
|
||||
|
||||
IStringLocalizer RealDBProducerPropertyLocalizer { get; set; }
|
||||
protected override Task OnParametersSetAsync()
|
||||
{
|
||||
RealDBProducerPropertyLocalizer = App.CreateLocalizerByType(Model.Value.GetType());
|
||||
|
||||
return base.OnParametersSetAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,9 @@ using BootstrapBlazor.Components;
|
||||
using Mapster;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Debug;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.NewLife;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
using ThingsGateway.Plugin.DB;
|
||||
using ThingsGateway.SqlSugar;
|
||||
@@ -29,7 +31,7 @@ public partial class QuestDBProducer : BusinessBaseWithCacheIntervalVariableMode
|
||||
private readonly QuestDBProducerVariableProperty _variablePropertys = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverPropertyUIType => typeof(RealDBProducerPropertyRazor);
|
||||
public override Type DriverPropertyUIType => typeof(SqlDBProducerPropertyRazor);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverUIType
|
||||
@@ -45,6 +47,13 @@ public partial class QuestDBProducer : BusinessBaseWithCacheIntervalVariableMode
|
||||
public override VariablePropertyBase VariablePropertys => _variablePropertys;
|
||||
|
||||
protected override BusinessPropertyWithCacheInterval _businessPropertyWithCacheInterval => _driverPropertys;
|
||||
private SqlSugarClient _db;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_db?.TryDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
public async Task<SqlSugarPagedList<IDBHistoryValue>> GetDBHistoryValuePagesAsync(DBHistoryValuePageInput input)
|
||||
{
|
||||
@@ -60,7 +69,7 @@ public partial class QuestDBProducer : BusinessBaseWithCacheIntervalVariableMode
|
||||
|
||||
protected override async Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
_db = BusinessDatabaseUtil.GetDb(_driverPropertys.DbType, _driverPropertys.BigTextConnectStr);
|
||||
_config = new TypeAdapterConfig();
|
||||
DateTime utcTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
_config.ForType<VariableRuntime, QuestDBHistoryValue>()
|
||||
@@ -153,20 +162,19 @@ public partial class QuestDBProducer : BusinessBaseWithCacheIntervalVariableMode
|
||||
protected override async Task ProtectedStartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
var db = BusinessDatabaseUtil.GetDb(_driverPropertys.DbType, _driverPropertys.BigTextConnectStr);
|
||||
db.DbMaintenance.CreateDatabase();
|
||||
_db.DbMaintenance.CreateDatabase();
|
||||
|
||||
//必须为间隔上传
|
||||
if (!_driverPropertys.BigTextScriptHistoryTable.IsNullOrEmpty())
|
||||
{
|
||||
DynamicSQLBase? hisModel = CSharpScriptEngineExtension.Do<DynamicSQLBase>(_driverPropertys.BigTextScriptHistoryTable);
|
||||
hisModel.Logger = LogMessage;
|
||||
await hisModel.DBInit(db, cancellationToken).ConfigureAwait(false);
|
||||
await hisModel.DBInit(_db, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
db.CodeFirst.As<QuestDBHistoryValue>(_driverPropertys.TableName).InitTables(typeof(QuestDBHistoryValue));
|
||||
_db.CodeFirst.As<QuestDBHistoryValue>(_driverPropertys.TableName).InitTables(typeof(QuestDBHistoryValue));
|
||||
}
|
||||
|
||||
await base.ProtectedStartAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user