Global.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. using System.Buffers.Text;
  2. using System.Text.Json;
  3. using System.Text.Json.Serialization;
  4. using AntDesign;
  5. using CSRedis;
  6. using AI.Platform.Core.Entity;
  7. using AI.Platform.Core.Util;
  8. using Microsoft.AspNetCore.Components;
  9. using Microsoft.AspNetCore.Http;
  10. using Microsoft.JSInterop;
  11. namespace AI.Platform.Core;
  12. public static class Global
  13. {
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. public static string? ConfigId { get { return Setting.Get<string>("dbConnection:connectionConfigs:0:configId"); } }
  18. /// <summary>
  19. ///
  20. /// </summary>
  21. public static string? ConnectionString { get { return Setting.Get<string>("dbConnection:connectionConfigs:0:connectionString"); } }
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. public static string? CacheConnectionString { get { return $"{Setting.Get<string>("Cache:RedisConnectionString")},prefix={Setting.Get<string>("Cache:InstanceName")}"; } }
  26. /// <summary>
  27. ///
  28. /// </summary>
  29. public static bool EnableInitTable { get { return Setting.Get<bool>("dbConnection:connectionConfigs:0:tableSettings:enableInitTable"); } }
  30. /// <summary>
  31. ///
  32. /// </summary>
  33. public static bool encryptResult { get { return Setting.Get<bool>("cryptogram:enabled"); } }
  34. /// <summary>
  35. ///
  36. /// </summary>
  37. public static string? CrypType { get { return Setting.Get<string>("cryptogram:cryptoType"); } }
  38. /// <summary>
  39. /// 登录过期时间
  40. /// </summary>
  41. public static int Expired { get { return Setting.Get<int>("App:ExpiredTime"); } }
  42. /// <summary>
  43. /// 上传地址
  44. /// </summary>
  45. public static string UploadUrl { get { return Setting.Get<string>("Upload:Url"); } }
  46. /// <summary>
  47. /// 媒体文件上传地址
  48. /// </summary>
  49. public static string MediaUploadUrl { get { return Setting.Get<string>("MediaUpload:Url"); } }
  50. /// <summary>
  51. /// 富文本apikey
  52. /// </summary>
  53. public static string TinyMCEApiKey { get { return Setting.Get<string>("TinyMCE:ApiKey"); } }
  54. /// <summary>
  55. ///
  56. /// </summary>
  57. public static CSRedisClient Redis { get; set; }
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. public static string CurrentPath { get; set; }
  62. /// <summary>
  63. ///
  64. /// </summary>
  65. public static long UserId { get; set; }
  66. /// <summary>
  67. ///
  68. /// </summary>
  69. public static SystemUser CurrentUser { get; set; }
  70. /// <summary>
  71. ///
  72. /// </summary>
  73. public static string? SystemName { get; set; }
  74. /// <summary>
  75. ///
  76. /// </summary>
  77. public static List<SystemMenu> Menus { get; set; } = new List<SystemMenu>();
  78. public static string Token { get; set; }
  79. public static string GetToken()
  80. {
  81. return "Bearer " + Token;
  82. }
  83. /// <summary>
  84. /// 获取host
  85. /// </summary>
  86. /// <param name="accessor"></param>
  87. /// <returns></returns>
  88. public static string GetHost(this IHttpContextAccessor accessor)
  89. {
  90. try
  91. {
  92. string host = accessor.HttpContext.Request.Headers["Host"];
  93. if (!string.IsNullOrWhiteSpace(host))
  94. {
  95. return $"{accessor.HttpContext.Request.Scheme}://{host}";
  96. }
  97. }
  98. catch (Exception ex) { }
  99. return "Empty Or Error Host";
  100. }
  101. /// <summary>
  102. /// 获取IP
  103. /// </summary>
  104. /// <param name="accessor"></param>
  105. /// <returns></returns>
  106. public static string GetIpv4(this IHttpContextAccessor accessor)
  107. {
  108. try
  109. {
  110. // 尝试从 X-Forwarded-For 头中获取真实 IP 地址
  111. var forwardedHeader = accessor.HttpContext.Request.Headers["X-Forwarded-For"];
  112. if (!string.IsNullOrEmpty(forwardedHeader))
  113. {
  114. // X-Forwarded-For 可能包含多个 IP 地址(逗号分隔),第一个是客户端的真实 IP
  115. return forwardedHeader.ToString().Split(',')[0].Trim();
  116. }
  117. // 如果没有 X-Forwarded-For 头,则回退到 RemoteIpAddress
  118. var remoteIpAddress = accessor.HttpContext.Connection.RemoteIpAddress;
  119. if (remoteIpAddress != null && remoteIpAddress.IsIPv4MappedToIPv6)
  120. {
  121. return remoteIpAddress.MapToIPv4().ToString();
  122. }
  123. }
  124. catch (Exception ex) { }
  125. return default;
  126. }
  127. public static async Task<SystemUser> GetUser(this IJSRuntime runtime)
  128. {
  129. var localStorageHelper = new LocalStorage(runtime);
  130. var user = await localStorageHelper.GetLocalStorage(LocalStorage.UserInfo);
  131. if (!string.IsNullOrWhiteSpace(user))
  132. {
  133. var suser = Crypto.AESDecrypt(user).ToEntity<SystemUser>();
  134. return suser;
  135. }
  136. return default;
  137. }
  138. public static SystemUser GetUserByToken(this IHttpContextAccessor accessor)
  139. {
  140. string token = accessor.HttpContext.Request.Headers["Authorization"];
  141. if (!string.IsNullOrEmpty(token))
  142. {
  143. token = token.Replace("Bearer ", "");
  144. var info = Jwt.Deserialize(token, out DateTime expired);
  145. if (info != null)
  146. {
  147. return new SystemUser() { Id = info.UserId, NickName = info.Name, };
  148. }
  149. }
  150. return null;
  151. }
  152. /// <summary>
  153. ///
  154. /// </summary>
  155. /// <param name="navigationManager"></param>
  156. public static void RedirectLogin(this Microsoft.AspNetCore.Components.NavigationManager navigationManager)
  157. {
  158. if (CurrentUser != null
  159. && CurrentUser.Id > 0
  160. && !string.IsNullOrWhiteSpace(CurrentUser.Account)
  161. && !string.IsNullOrWhiteSpace(CurrentUser.Password))
  162. return;
  163. try
  164. {
  165. // forceLoad 使用浏览器直接加载页面,绕过需要 JS 的客户端路由
  166. navigationManager?.NavigateTo("/account/login", forceLoad: true);
  167. }
  168. catch (NavigationException)
  169. {
  170. // 如果在 prerender 阶段仍可能抛异常,忽略并在首次渲染后再导航
  171. }
  172. }
  173. public static async Task RedirectLogin(this Microsoft.AspNetCore.Components.NavigationManager navigationManager, IJSRuntime jSRuntime)
  174. {
  175. var localStorageHelper = new LocalStorage(jSRuntime);
  176. var json = await localStorageHelper.GetLocalStorage(LocalStorage.UserInfo);
  177. var user = Crypto.AESDecrypt(json).ToEntity<SystemUser>();
  178. if (user != null
  179. && user.Id > 0
  180. && !string.IsNullOrWhiteSpace(user.Account)
  181. && !string.IsNullOrWhiteSpace(user.Password))
  182. {
  183. if (user.Expired.Subtract(DateTime.Now).TotalDays > 0 && CurrentUser != null && user.Id == CurrentUser.Id)
  184. {
  185. return;
  186. }
  187. else
  188. {
  189. await localStorageHelper.RemoveLocalStorage(LocalStorage.AutoLogin);
  190. await localStorageHelper.RemoveLocalStorage(LocalStorage.UserInfo);
  191. }
  192. }
  193. navigationManager?.NavigateTo("/account/login");
  194. }
  195. }
  196. public class LongToDateTimeConverter : JsonConverter<DateTime>
  197. {
  198. public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  199. {
  200. if (Utf8Parser.TryParse(reader.ValueSpan, out long value, out _))
  201. return DateTime.UnixEpoch.AddMilliseconds(value);
  202. throw new FormatException();
  203. }
  204. public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
  205. {
  206. writer.WriteStringValue(
  207. JsonEncodedText.Encode(((long)(value - DateTime.UnixEpoch).TotalMilliseconds).ToString()));
  208. }
  209. }