RiskControlCore.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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. try
  120. {
  121. var redisServer = EndPointCore.GetRedisServer(node);
  122. if (string.IsNullOrEmpty(redisServer)) return 0;
  123. var cacheKey = $"RiskControl:{key}:calls:{flag}";
  124. using var scope = await RedisClientFactory.CreateScopeAsync(redisServer);
  125. return await scope.Client.GetAsync<int>(cacheKey);
  126. }
  127. catch (Exception ex) { }
  128. return 0;
  129. });
  130. var results = await Task.WhenAll(tasks);
  131. var totalCalls = results.Sum();
  132. _calls.TryAdd(key, totalCalls);
  133. return totalCalls;
  134. }
  135. catch (Exception)
  136. {
  137. // TODO: 添加日志
  138. return 0;
  139. }
  140. }
  141. public static int GetCalls(TkChannelEnum channel, int accountId, string flag)
  142. {
  143. try
  144. {
  145. string key = $"{channel}:{accountId}:{flag}";
  146. if (_calls.ContainsKey(key)) return _calls[key];
  147. string cache_key = $"RiskControl:{key}:calls:{flag}";
  148. int num = RedisHelper.Get<int>(cache_key);
  149. _calls.TryAdd(key, num);
  150. return num;
  151. }
  152. catch (Exception ex) { return 0; }
  153. }
  154. internal static async Task SaveIncomeAmtAsync(TkChannelEnum channel, string accountName, decimal income_amt)
  155. {
  156. string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}";
  157. lock (_incomeAmt)
  158. {
  159. if (!_incomeAmt.TryAdd(key, income_amt))
  160. _incomeAmt[key] = income_amt;
  161. }
  162. string cache_key = $"RiskControl:{key}:income_amt";
  163. try
  164. {
  165. var tasks = EndPointCore.List()
  166. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  167. .Select(async node =>
  168. {
  169. try
  170. {
  171. var redisServer = EndPointCore.GetRedisServer(node);
  172. if (string.IsNullOrEmpty(redisServer)) return false;
  173. using var scope = await RedisClientFactory.CreateScopeAsync(redisServer);
  174. return await scope.Client.SetAsync(cache_key, income_amt, 3 * 86400);
  175. }
  176. catch (Exception ex)
  177. {
  178. return false;
  179. }
  180. });
  181. await Task.WhenAll(tasks);
  182. }
  183. catch (Exception)
  184. {
  185. }
  186. }
  187. public static decimal GetIncomeAmt(TkChannelEnum channel, string accountName)
  188. {
  189. try
  190. {
  191. string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}";
  192. if (_incomeAmt.ContainsKey(key)) return _incomeAmt[key];
  193. string cache_key = $"RiskControl:{key}:income_amt";
  194. return RedisHelper.Get<decimal>(cache_key);
  195. }
  196. catch (Exception ex) { return 0; }
  197. }
  198. }
  199. }