OverrideRuleCore.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using dodohold.core;
  2. using System.Data;
  3. using System.Text.RegularExpressions;
  4. using YunhuiKit;
  5. namespace molilian.core
  6. {
  7. public partial class OverrideRuleCore
  8. {
  9. private static IEnumerable<OverrideRuleDTO> _cached;
  10. private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
  11. public static async Task<IEnumerable<OverrideRuleDTO>> ListAsync(bool force = false)
  12. {
  13. if (!force && _cached != null) return _cached;
  14. try
  15. {
  16. await _semaphore.WaitAsync();
  17. // 如果缓存存在且未强制刷新,直接返回
  18. if (!force && _cached != null) return _cached;
  19. string cache_key = $"cache:tk_override_rules";
  20. IEnumerable<OverrideRuleDTO>? list = null;
  21. // 尝试从Redis获取数据
  22. try
  23. {
  24. list = await RedisKit.GetAsync<IEnumerable<OverrideRuleDTO>>(cache_key);
  25. }
  26. catch (Exception ex)
  27. {
  28. // 记录Redis错误
  29. _ = new LoggerLibrary("OverrideRule", "Redis").Info(ex.Message, ex.StackTrace).SaveAsync();
  30. }
  31. // 如果Redis获取失败或需要强制刷新
  32. if (force || list == null)
  33. {
  34. try
  35. {
  36. list = new DBContext.Table("tk_override_rules")
  37. .Where("status=@status", new { status = 1 })
  38. .Order("sort DESC, id DESC")
  39. .Select<OverrideRuleDTO>();
  40. if (list != null && list.Any())
  41. {
  42. // 尝试更新Redis缓存
  43. try
  44. {
  45. await RedisKit.SetAsync(cache_key, list, 30 * 86400);
  46. }
  47. catch (Exception ex)
  48. {
  49. // 记录Redis更新错误
  50. _ = new LoggerLibrary("OverrideRule", "Redis").Info(ex.Message, ex.StackTrace).SaveAsync();
  51. }
  52. }
  53. }
  54. catch (Exception ex)
  55. {
  56. // 记录数据库查询错误
  57. _ = new LoggerLibrary("OverrideRule", "Database").Info(ex.Message, ex.StackTrace).SaveAsync();
  58. // 如果数据库查询失败但缓存还在,继续使用缓存
  59. if (_cached != null) return _cached;
  60. throw; // 如果没有任何可用数据,则抛出异常
  61. }
  62. }
  63. _cached = list;
  64. return list ?? [];
  65. }
  66. finally
  67. {
  68. _semaphore.Release();
  69. }
  70. }
  71. public static async Task<OverrideRuleDTO> ProcessAsync(string content)
  72. {
  73. var list = await ListAsync();
  74. foreach (var item in list)
  75. {
  76. if (!"tk".Equals(item.platform)) continue;
  77. if (string.IsNullOrEmpty(item.original_text)) continue;
  78. switch (item.rule)
  79. {
  80. case "regex":
  81. Match match = Regex.Match(content, item.original_text);
  82. if (!match.Success) continue;
  83. return item;
  84. default:
  85. if (!content.Contains(item.original_text)) continue;
  86. return item;
  87. }
  88. }
  89. return null;
  90. }
  91. public static void Refresh()
  92. {
  93. _cached = null;
  94. _ = ListAsync(true);
  95. }
  96. public static int Update(OverrideRuleDTO data, IDbConnection conn)
  97. {
  98. var result = (int)conn.Update<OverrideRuleDTO>(data, new { data.id });
  99. _ = ListAsync(true);
  100. #if DEBUG
  101. #else
  102. EndPointCore.NotifyReload();
  103. #endif
  104. return result;
  105. }
  106. public static int Create(OverrideRuleDTO data, IDbConnection conn)
  107. {
  108. var result = (int)conn.Insert(data);
  109. _ = ListAsync(true);
  110. #if DEBUG
  111. #else
  112. EndPointCore.NotifyReload();
  113. #endif
  114. return result;
  115. }
  116. }
  117. }