RiskControlCore.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc.Controllers;
  3. using Microsoft.AspNetCore.Mvc.Filters;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using dodohold.core;
  9. using System.Threading.Channels;
  10. using YunhuiKit;
  11. namespace molilian.core
  12. {
  13. public partial class RiskControlCore
  14. {
  15. private static Dictionary<string, int> _calls = new();
  16. private static Dictionary<string, decimal> _incomeAmt = new();
  17. public static void Refresh()
  18. {
  19. _incomeAmt = [];
  20. }
  21. public static void ResetCalls()
  22. {
  23. _calls = [];
  24. }
  25. internal static async Task CallsIncrByAsync(TkChannelEnum channel, int accountId)
  26. {
  27. await CallsIncrByAsync(channel, accountId, DateTime.Now.ToString("yyyyMMdd"));
  28. await CallsIncrByAsync(channel, accountId, DateTime.Now.ToString("yyyyMMddHH"));
  29. }
  30. internal static async Task CallsIncrByAsync(TkChannelEnum channel, int accountId, string flag)
  31. {
  32. string key = $"{channel}:{accountId}:{flag}";
  33. if (_calls.ContainsKey(key))
  34. {
  35. _calls[key] += 1;
  36. }
  37. else
  38. {
  39. _calls[key] = 1;
  40. }
  41. string cache_key = $"RiskControl:{key}:calls:{flag}";
  42. await RedisKit.IncrByAsync(cache_key);
  43. await RedisKit.ExpireAsync(cache_key, 3 * 86400);
  44. }
  45. internal static void CallsIncrBy(TkChannelEnum channel, int accountId)
  46. {
  47. CallsIncrBy(channel, accountId, DateTime.Now.ToString("yyyyMMdd"));
  48. CallsIncrBy(channel, accountId, DateTime.Now.ToString("yyyyMMddHH"));
  49. }
  50. internal static void CallsIncrBy(TkChannelEnum channel, int accountId, string flag)
  51. {
  52. string key = $"{channel}:{accountId}:{flag}";
  53. if (_calls.ContainsKey(key))
  54. {
  55. _calls[key] += 1;
  56. }
  57. else
  58. {
  59. _calls[key] = 1;
  60. }
  61. string cache_key = $"RiskControl:{key}:calls:{flag}";
  62. RedisHelper.IncrBy(cache_key);
  63. RedisHelper.Expire(cache_key, 3 * 86400);
  64. }
  65. internal static async Task SetCallsAsync(TkChannelEnum channel, int accountId, string flag, int val)
  66. {
  67. string key = $"{channel}:{accountId}:{flag}";
  68. if (_calls.ContainsKey(key))
  69. {
  70. _calls[key] = val;
  71. }
  72. else
  73. {
  74. _calls[key] = val;
  75. }
  76. string cache_key = $"RiskControl:{key}:calls:{flag}";
  77. RedisHelper.IncrByAsync(cache_key);
  78. RedisHelper.ExpireAsync(cache_key, 3 * 86400);
  79. }
  80. // public static int GetAllNodesCalls(TkChannelEnum channel, int accountId, string flag)
  81. // {
  82. // string key = $"{channel}:{accountId}:{flag}";
  83. // var result = EndPointCore.ProcessEndPointNodes<int>(node =>
  84. // {
  85. // if (!node.is_public_api) return 0;
  86. // if (string.IsNullOrEmpty(node.redis_server)) return 0;
  87. //#if DEBUG
  88. // switch (node.name)
  89. // {
  90. // case "bj":
  91. // node.redis_server = "101.200.46.46:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
  92. // break;
  93. // case "gz":
  94. // node.redis_server = "8.138.110.158:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
  95. // break;
  96. // case "coupon1":
  97. // node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
  98. // break;
  99. // default: return 0;
  100. // }
  101. //#endif
  102. // string cache_key = $"RiskControl:{key}:calls:{flag}";
  103. // var redis = RedisClientManager.GetRedisClient(node.redis_server);
  104. // return redis.Get<int>(cache_key);
  105. // });
  106. // int num = result.Sum();
  107. // _calls.TryAdd(key, num);
  108. // return num;
  109. // }
  110. public static async Task<int> GetAllNodesCallsAsync(TkChannelEnum channel, int accountId, string flag)
  111. {
  112. var key = $"{channel}:{accountId}:{flag}";
  113. try
  114. {
  115. var tasks = EndPointCore.List()
  116. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  117. .Select(async node =>
  118. {
  119. var redisServer = EndPointCore.GetRedisServer(node);
  120. if (string.IsNullOrEmpty(redisServer)) return 0;
  121. var cacheKey = $"RiskControl:{key}:calls:{flag}";
  122. using var scope = await RedisClientFactory.CreateScopeAsync(redisServer);
  123. return await scope.Client.GetAsync<int>(cacheKey);
  124. });
  125. var results = await Task.WhenAll(tasks);
  126. var totalCalls = results.Sum();
  127. _calls.TryAdd(key, totalCalls);
  128. return totalCalls;
  129. }
  130. catch (Exception)
  131. {
  132. // TODO: 添加日志
  133. return 0;
  134. }
  135. }
  136. public static int GetCalls(TkChannelEnum channel, int accountId, string flag)
  137. {
  138. try
  139. {
  140. string key = $"{channel}:{accountId}:{flag}";
  141. if (_calls.ContainsKey(key)) return _calls[key];
  142. string cache_key = $"RiskControl:{key}:calls:{flag}";
  143. int num = RedisHelper.Get<int>(cache_key);
  144. _calls.TryAdd(key, num);
  145. return num;
  146. }
  147. catch (Exception ex) { return 0; }
  148. }
  149. internal static async Task SaveIncomeAmtAsync(TkChannelEnum channel, string accountName, decimal income_amt)
  150. {
  151. string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}";
  152. lock (_incomeAmt)
  153. {
  154. if (!_incomeAmt.TryAdd(key, income_amt))
  155. _incomeAmt[key] = income_amt;
  156. }
  157. string cache_key = $"RiskControl:{key}:income_amt";
  158. try
  159. {
  160. var tasks = EndPointCore.List()
  161. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  162. .Select(async node =>
  163. {
  164. var redisServer = EndPointCore.GetRedisServer(node);
  165. if (string.IsNullOrEmpty(redisServer)) return false;
  166. using var scope = await RedisClientFactory.CreateScopeAsync(redisServer);
  167. return await scope.Client.SetAsync(cache_key, income_amt, 3 * 86400);
  168. });
  169. await Task.WhenAll(tasks);
  170. }
  171. catch (Exception)
  172. {
  173. }
  174. }
  175. public static decimal GetIncomeAmt(TkChannelEnum channel, string accountName)
  176. {
  177. try
  178. {
  179. string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}";
  180. if (_incomeAmt.ContainsKey(key)) return _incomeAmt[key];
  181. string cache_key = $"RiskControl:{key}:income_amt";
  182. return RedisHelper.Get<decimal>(cache_key);
  183. }
  184. catch (Exception ex) { return 0; }
  185. }
  186. }
  187. }