ElePoolCore.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using dodohold.core;
  2. namespace molilian.core
  3. {
  4. public partial class ElePoolCore
  5. {
  6. private static string _end_point;
  7. private static Dictionary<string, decimal> _incomeAmt = new();
  8. private static Dictionary<string, int> _calls = new();
  9. static ElePoolCore()
  10. {
  11. _end_point = Environment.GetEnvironmentVariable("EndPoint");
  12. }
  13. private static readonly object _lockObj = new();
  14. private static IEnumerable<ElePoolDTO> _cached;
  15. public static ElePoolDTO? GetOne()
  16. {
  17. var list = List();
  18. if (!list.Any()) return null;
  19. return list.Where(IsNotExceedDailyIncomeLimit).OrderBy(l => Guid.NewGuid()).FirstOrDefault();
  20. }
  21. public static ElePoolDTO? GetOne(int id)
  22. {
  23. var list = List();
  24. if (!list.Any()) return null;
  25. return list.Where(e => e.id == id && IsNotExceedDailyIncomeLimit(e)).FirstOrDefault();
  26. }
  27. internal static void CallsIncrBy(int accountId)
  28. {
  29. CallsIncrBy(accountId, DateTime.Now.ToString("yyyyMMdd"));
  30. CallsIncrBy(accountId, DateTime.Now.ToString("yyyyMMddHH"));
  31. }
  32. internal static void CallsIncrBy(int accountId, string flag)
  33. {
  34. string key = $"{accountId}:{flag}";
  35. if (_calls.ContainsKey(key))
  36. {
  37. _calls[key] = _calls[key] + 1;
  38. }
  39. else
  40. {
  41. _calls[key] = 1;
  42. }
  43. string cache_key = $"cache:ele_pool:{key}:calls:{flag}";
  44. RedisHelper.IncrBy(cache_key);
  45. RedisHelper.Expire(cache_key, 3 * 86400);
  46. }
  47. public static int SaveCalls(int accountId, string flag)
  48. {
  49. string key = $"{accountId}:{flag}";
  50. var result = EndPointCore.ProcessEndPointNodes<int>(node =>
  51. {
  52. if (!node.is_public_api) return 0;
  53. if (string.IsNullOrEmpty(node.redis_server)) return 0;
  54. #if DEBUG
  55. switch (node.name)
  56. {
  57. case "bj":
  58. node.redis_server = "101.200.46.46:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
  59. break;
  60. case "gz":
  61. node.redis_server = "8.138.110.158:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
  62. break;
  63. case "coupon1":
  64. node.redis_server = "c1api.molilian.com:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
  65. break;
  66. default: return 0;
  67. }
  68. #endif
  69. string cache_key = $"cache:ele_pool:{key}:calls:{flag}";
  70. var redis = RedisClientManager.GetRedisClient(node.redis_server);
  71. return redis.Get<int>(cache_key);
  72. });
  73. int num = result.Sum();
  74. _calls.TryAdd(key, num);
  75. return num;
  76. }
  77. public static int GetCalls(int accountId, string flag)
  78. {
  79. try
  80. {
  81. string key = $"{accountId}:{flag}";
  82. if (_calls.ContainsKey(key)) return _calls[key];
  83. string cache_key = $"cache:ele_pool:{key}:calls:{flag}";
  84. int num = RedisHelper.Get<int>(cache_key);
  85. _calls.TryAdd(key, num);
  86. return num;
  87. }
  88. catch (Exception ex) { return 0; }
  89. }
  90. private static bool IsNotExceedDailyIncomeLimit(ElePoolDTO item)
  91. {
  92. if (!string.IsNullOrEmpty(_end_point) && !string.IsNullOrEmpty(item.end_point))
  93. {
  94. if (item.end_point != _end_point) return false;
  95. }
  96. // 使用初始化参数创建工作时间表
  97. if (!new WorkSchedule(item.time_range).IsWorkHour()) return false;
  98. if (item.daily_calls_limit > 0)
  99. {
  100. int daily_num = GetCalls(item.id, DateTime.Now.ToString("yyyyMMdd"));
  101. if (daily_num >= item.daily_calls_limit) return false;
  102. }
  103. if (item.hourly_calls_limit > 0)
  104. {
  105. int hourly_num = GetCalls(item.id, DateTime.Now.ToString("yyyyMMddHH"));
  106. if (hourly_num >= item.hourly_calls_limit) return false;
  107. }
  108. return true;
  109. }
  110. public static IEnumerable<ElePoolDTO> List(bool force = false)
  111. {
  112. if (!force && _cached != null) return _cached;
  113. string cache_key = $"cache:ele_pool";
  114. var list = RedisHelper.Get<IEnumerable<ElePoolDTO>>(cache_key);
  115. if (force || list == null)
  116. {
  117. lock (_lockObj)
  118. {
  119. list = new DBContext.Table("ele_pool")
  120. .Where("status=@status", new { status = 1 })
  121. .Select<ElePoolDTO>();
  122. if (list == null) return default;
  123. _calls = new Dictionary<string, int>();
  124. foreach (var item in list)
  125. {
  126. string key = $"{item.id}:{DateTime.Now:yyyyMMddHH}";
  127. _calls.TryAdd(key, item.current_hourly_calls);
  128. key = $"{item.id}:{DateTime.Now:yyyyMMddHH}";
  129. _calls.TryAdd(key, item.current_daily_calls);
  130. }
  131. RedisHelper.Set(cache_key, list, 30 * 86400);
  132. }
  133. }
  134. _cached = list;
  135. return list;
  136. }
  137. public static void Refresh()
  138. {
  139. _ = List(true);
  140. }
  141. internal static void AccountExhausted()
  142. {
  143. string cache_key = $"cache:tk_pool:account:exhausted";
  144. long count = RedisHelper.IncrBy(cache_key);
  145. if (count > 1) return;
  146. RedisHelper.Expire(cache_key, 3600);
  147. NotifyCore.Notify(new NifyMessage
  148. {
  149. message = $"【京东联盟】没有匹配账号",
  150. priority = NifyMessagePriority.high,
  151. tags = ["red_circle"]
  152. });
  153. NotifyCore.AnPushNotify("没账号", $"【京东联盟】没有匹配账号");
  154. }
  155. }
  156. }