using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Text; using dodohold.core; using System.Threading.Channels; using YunhuiKit; namespace molilian.core { public partial class RiskControlCore { private static Dictionary _calls = new(); private static Dictionary _incomeAmt = new(); public static void Refresh() { _incomeAmt = []; } public static void ResetCalls() { _calls = []; } internal static async Task CallsIncrByAsync(TkChannelEnum channel, int accountId) { await CallsIncrByAsync(channel, accountId, DateTime.Now.ToString("yyyyMMdd")); await CallsIncrByAsync(channel, accountId, DateTime.Now.ToString("yyyyMMddHH")); } internal static async Task CallsIncrByAsync(TkChannelEnum channel, int accountId, string flag) { string key = $"{channel}:{accountId}:{flag}"; if (_calls.ContainsKey(key)) { _calls[key] += 1; } else { _calls[key] = 1; } string cache_key = $"RiskControl:{key}:calls:{flag}"; await RedisKit.IncrByAsync(cache_key); await RedisKit.ExpireAsync(cache_key, 3 * 86400); } internal static void CallsIncrBy(TkChannelEnum channel, int accountId) { CallsIncrBy(channel, accountId, DateTime.Now.ToString("yyyyMMdd")); CallsIncrBy(channel, accountId, DateTime.Now.ToString("yyyyMMddHH")); } internal static void CallsIncrBy(TkChannelEnum channel, int accountId, string flag) { string key = $"{channel}:{accountId}:{flag}"; if (_calls.ContainsKey(key)) { _calls[key] += 1; } else { _calls[key] = 1; } string cache_key = $"RiskControl:{key}:calls:{flag}"; RedisHelper.IncrBy(cache_key); RedisHelper.Expire(cache_key, 3 * 86400); } internal static async Task SetCallsAsync(TkChannelEnum channel, int accountId, string flag, int val) { string key = $"{channel}:{accountId}:{flag}"; if (_calls.ContainsKey(key)) { _calls[key] = val; } else { _calls[key] = val; } string cache_key = $"RiskControl:{key}:calls:{flag}"; RedisHelper.IncrByAsync(cache_key); RedisHelper.ExpireAsync(cache_key, 3 * 86400); } // public static int GetAllNodesCalls(TkChannelEnum channel, int accountId, string flag) // { // string key = $"{channel}:{accountId}:{flag}"; // var result = EndPointCore.ProcessEndPointNodes(node => // { // if (!node.is_public_api) return 0; // if (string.IsNullOrEmpty(node.redis_server)) return 0; //#if DEBUG // switch (node.name) // { // case "bj": // node.redis_server = "101.200.46.46:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook"; // break; // case "gz": // node.redis_server = "8.138.110.158:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook"; // break; // case "coupon1": // node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon"; // break; // default: return 0; // } //#endif // string cache_key = $"RiskControl:{key}:calls:{flag}"; // var redis = RedisClientManager.GetRedisClient(node.redis_server); // return redis.Get(cache_key); // }); // int num = result.Sum(); // _calls.TryAdd(key, num); // return num; // } public static async Task GetAllNodesCallsAsync(TkChannelEnum channel, int accountId, string flag) { var key = $"{channel}:{accountId}:{flag}"; try { var tasks = EndPointCore.List() .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server)) .Select(async node => { var redisServer = EndPointCore.GetRedisServer(node); if (string.IsNullOrEmpty(redisServer)) return 0; var cacheKey = $"RiskControl:{key}:calls:{flag}"; using var scope = RedisClientFactory.CreateScope(redisServer); return await scope.Client.GetAsync(cacheKey); }); var results = await Task.WhenAll(tasks); var totalCalls = results.Sum(); _calls.TryAdd(key, totalCalls); return totalCalls; } catch (Exception) { // TODO: 添加日志 return 0; } } public static int GetCalls(TkChannelEnum channel, int accountId, string flag) { try { string key = $"{channel}:{accountId}:{flag}"; if (_calls.ContainsKey(key)) return _calls[key]; string cache_key = $"RiskControl:{key}:calls:{flag}"; int num = RedisHelper.Get(cache_key); _calls.TryAdd(key, num); return num; } catch (Exception ex) { return 0; } } internal static async Task SaveIncomeAmtAsync(TkChannelEnum channel, string accountName, decimal income_amt) { string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}"; lock (_incomeAmt) { if (!_incomeAmt.TryAdd(key, income_amt)) _incomeAmt[key] = income_amt; } string cache_key = $"RiskControl:{key}:income_amt"; try { var tasks = EndPointCore.List() .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server)) .Select(async node => { var redisServer = EndPointCore.GetRedisServer(node); if (string.IsNullOrEmpty(redisServer)) return false; using var scope = RedisClientFactory.CreateScope(redisServer); return await scope.Client.SetAsync(cache_key, income_amt, 3 * 86400); }); await Task.WhenAll(tasks); } catch (Exception) { } } public static decimal GetIncomeAmt(TkChannelEnum channel, string accountName) { try { string key = $"{channel}:{accountName}:{DateTime.Now:yyyyMMdd}"; if (_incomeAmt.ContainsKey(key)) return _incomeAmt[key]; string cache_key = $"RiskControl:{key}:income_amt"; return RedisHelper.Get(cache_key); } catch (Exception ex) { return 0; } } } }