RiskControlCore.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. await RedisHelper.IncrByAsync(cache_key);
  78. await RedisHelper.ExpireAsync(cache_key, 3 * 86400);
  79. }
  80. public static async Task<int> GetAllNodesCallsAsync(TkChannelEnum channel, int accountId, string flag)
  81. {
  82. var key = $"{channel}:{accountId}:{flag}";
  83. try
  84. {
  85. var tasks = EndPointCore.List()
  86. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  87. .Select(async node =>
  88. {
  89. try
  90. {
  91. var redisServer = EndPointCore.GetRedisServer(node);
  92. if (string.IsNullOrEmpty(redisServer)) return 0;
  93. var cacheKey = $"RiskControl:{key}:calls:{flag}";
  94. using var scope = await RedisClientFactory.CreateScopeAsync(redisServer);
  95. return await scope.Client.GetAsync<int>(cacheKey);
  96. }
  97. catch (Exception ex) { }
  98. return 0;
  99. });
  100. var results = await Task.WhenAll(tasks);
  101. var totalCalls = results.Sum();
  102. _calls.TryAdd(key, totalCalls);
  103. return totalCalls;
  104. }
  105. catch (Exception)
  106. {
  107. // TODO: 添加日志
  108. return 0;
  109. }
  110. }
  111. internal static async Task SetTkEndpointCallsAsync(int accountId, int ep_id, string flag, int val)
  112. {
  113. string key = $"tk_endpoint:{accountId}:{ep_id}:{flag}";
  114. if (_calls.ContainsKey(key))
  115. {
  116. _calls[key] = val;
  117. }
  118. else
  119. {
  120. _calls[key] = val;
  121. }
  122. string cache_key = $"RiskControl:{key}:calls:{flag}";
  123. await RedisHelper.IncrByAsync(cache_key);
  124. await RedisHelper.ExpireAsync(cache_key, 3 * 86400);
  125. }
  126. public static async Task<int> GetAllNodesTkEndpointCallsAsync(int accountId, int ep_id, string flag)
  127. {
  128. string key = $"tk_endpoint:{accountId}:{ep_id}:{flag}";
  129. try
  130. {
  131. var tasks = EndPointCore.List()
  132. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  133. .Select(async node =>
  134. {
  135. try
  136. {
  137. var redisServer = EndPointCore.GetRedisServer(node);
  138. if (string.IsNullOrEmpty(redisServer)) return 0;
  139. string cacheKey = $"RiskControl:{key}:calls:{flag}";
  140. using var scope = await RedisClientFactory.CreateScopeAsync(redisServer);
  141. return await scope.Client.GetAsync<int>(cacheKey);
  142. }
  143. catch (Exception ex) { }
  144. return 0;
  145. });
  146. var results = await Task.WhenAll(tasks);
  147. var totalCalls = results.Sum();
  148. _calls.TryAdd(key, totalCalls);
  149. return totalCalls;
  150. }
  151. catch (Exception)
  152. {
  153. // TODO: 添加日志
  154. return 0;
  155. }
  156. }
  157. public static int GetCalls(TkChannelEnum channel, int accountId, string flag)
  158. {
  159. try
  160. {
  161. string key = $"{channel}:{accountId}:{flag}";
  162. if (_calls.ContainsKey(key)) return _calls[key];
  163. string cache_key = $"RiskControl:{key}:calls:{flag}";
  164. int num = RedisHelper.Get<int>(cache_key);
  165. _calls.TryAdd(key, num);
  166. return num;
  167. }
  168. catch (Exception ex) { return 0; }
  169. }
  170. internal static async Task SaveIncomeAmtAsync(TkChannelEnum channel, string accountName, decimal income_amt)
  171. {
  172. string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}";
  173. lock (_incomeAmt)
  174. {
  175. if (!_incomeAmt.TryAdd(key, income_amt))
  176. _incomeAmt[key] = income_amt;
  177. }
  178. string cache_key = $"RiskControl:{key}:income_amt";
  179. try
  180. {
  181. var tasks = EndPointCore.List()
  182. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  183. .Select(async node =>
  184. {
  185. try
  186. {
  187. var redisServer = EndPointCore.GetRedisServer(node);
  188. if (string.IsNullOrEmpty(redisServer)) return false;
  189. using var scope = await RedisClientFactory.CreateScopeAsync(redisServer);
  190. return await scope.Client.SetAsync(cache_key, income_amt, 3 * 86400);
  191. }
  192. catch (Exception ex)
  193. {
  194. return false;
  195. }
  196. });
  197. await Task.WhenAll(tasks);
  198. }
  199. catch (Exception)
  200. {
  201. }
  202. }
  203. public static decimal GetIncomeAmt(TkChannelEnum channel, string accountName)
  204. {
  205. try
  206. {
  207. string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}";
  208. if (_incomeAmt.ContainsKey(key)) return _incomeAmt[key];
  209. string cache_key = $"RiskControl:{key}:income_amt";
  210. return RedisHelper.Get<decimal>(cache_key);
  211. }
  212. catch (Exception ex) { return 0; }
  213. }
  214. }
  215. }