|
@@ -0,0 +1,319 @@
|
|
|
|
|
+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 Dataoke;
|
|
|
|
|
+using Google.Protobuf.WellKnownTypes;
|
|
|
|
|
+using System.Diagnostics;
|
|
|
|
|
+using System.Text.Json;
|
|
|
|
|
+using TencentCloud.Tcm.V20210413.Models;
|
|
|
|
|
+using System.Security.Cryptography;
|
|
|
|
|
+using System.Collections.Concurrent;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+namespace molilian.core
|
|
|
|
|
+{
|
|
|
|
|
+ public partial class PddPoolCore
|
|
|
|
|
+ {
|
|
|
|
|
+ private static readonly object _lockObj = new();
|
|
|
|
|
+ private static IEnumerable<PddPoolDTO> _cached;
|
|
|
|
|
+
|
|
|
|
|
+ private static string _end_point;
|
|
|
|
|
+ private static Dictionary<string, decimal> _incomeAmt = new();
|
|
|
|
|
+ private static Dictionary<string, int> _calls = new();
|
|
|
|
|
+ private static ConcurrentDictionary<int, DateTime> _suspend = new();
|
|
|
|
|
+ static PddPoolCore()
|
|
|
|
|
+ {
|
|
|
|
|
+ _end_point = Environment.GetEnvironmentVariable("EndPoint");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static PddPoolDTO? GetOne(PddUnionWorkMode mode, int accountid = 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ var list = List();
|
|
|
|
|
+ if (!list.Any()) return null;
|
|
|
|
|
+ return list.Where(e => IsMatch(e, mode, accountid)).FirstOrDefault();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ internal static void TempSuspend(int accountId)
|
|
|
|
|
+ {
|
|
|
|
|
+ _suspend.AddOrUpdate(accountId, DateTime.Now, (key, oldValue) => DateTime.Now);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private static bool IsMatch(PddPoolDTO item, PddUnionWorkMode mode, int accountid)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (accountid != 0 && accountid != item.id) return false;
|
|
|
|
|
+ if (mode != PddUnionWorkMode.All && mode != item.work_mode) return false;
|
|
|
|
|
+
|
|
|
|
|
+ if (!string.IsNullOrEmpty(_end_point) && !string.IsNullOrEmpty(item.end_point))
|
|
|
|
|
+ {
|
|
|
|
|
+ if (item.end_point != _end_point) return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 使用初始化参数创建工作时间表
|
|
|
|
|
+ if (!new WorkSchedule(item.time_range).IsWorkHour()) return false;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ if (_suspend.TryGetValue(accountid, out DateTime suspendTime))
|
|
|
|
|
+ {
|
|
|
|
|
+ var ts = DateTime.Now - suspendTime;
|
|
|
|
|
+ if (ts.TotalSeconds < 70) return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (item.daily_calls_limit > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ int daily_num = GetCalls(item.id, DateTime.Now.ToString("yyyyMMdd"));
|
|
|
|
|
+ if (daily_num >= item.daily_calls_limit) return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.hourly_calls_limit > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ int hourly_num = GetCalls(item.id, DateTime.Now.ToString("yyyyMMddHH"));
|
|
|
|
|
+ if (hourly_num >= item.hourly_calls_limit) return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static int GetCalls(int accountId, string flag)
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ string key = $"{accountId}:{flag}";
|
|
|
|
|
+ if (_calls.ContainsKey(key)) return _calls[key];
|
|
|
|
|
+
|
|
|
|
|
+ string cache_key = $"cache:jd_pool:{key}:calls:{flag}";
|
|
|
|
|
+ int num = RedisHelper.Get<int>(cache_key);
|
|
|
|
|
+ _calls.TryAdd(key, num);
|
|
|
|
|
+ return num;
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex) { return 0; }
|
|
|
|
|
+ }
|
|
|
|
|
+ internal static void CallsIncrBy(int accountId)
|
|
|
|
|
+ {
|
|
|
|
|
+ CallsIncrBy(accountId, DateTime.Now.ToString("yyyyMMdd"));
|
|
|
|
|
+ CallsIncrBy(accountId, DateTime.Now.ToString("yyyyMMddHH"));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ internal static void CallsIncrBy(int accountId, string flag)
|
|
|
|
|
+ {
|
|
|
|
|
+ string key = $"{accountId}:{flag}";
|
|
|
|
|
+ if (_calls.ContainsKey(key))
|
|
|
|
|
+ {
|
|
|
|
|
+ _calls[key] = _calls[key] + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ _calls[key] = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ string cache_key = $"cache:pdd_pool:{key}:calls:{flag}";
|
|
|
|
|
+ RedisHelper.IncrBy(cache_key);
|
|
|
|
|
+ RedisHelper.Expire(cache_key, 3 * 86400);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static int SaveCalls(int accountId, string flag)
|
|
|
|
|
+ {
|
|
|
|
|
+ string key = $"{accountId}:{flag}";
|
|
|
|
|
+ var result = EndPointCore.ProcessEndPointNodes<int>(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 = "c1api.molilian.com:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
|
|
|
|
|
+ break;
|
|
|
|
|
+ default: return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+ string cache_key = $"cache:pdd_pool:{key}:calls:{flag}";
|
|
|
|
|
+ var redis = RedisClientManager.GetRedisClient(node.redis_server);
|
|
|
|
|
+ return redis.Get<int>(cache_key);
|
|
|
|
|
+ });
|
|
|
|
|
+ int num = result.Sum();
|
|
|
|
|
+ _calls.TryAdd(key, num);
|
|
|
|
|
+ return num;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static IEnumerable<PddPoolDTO> List(bool force = false)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!force && _cached != null) return _cached;
|
|
|
|
|
+
|
|
|
|
|
+ string cache_key = $"cache:pdd_pool";
|
|
|
|
|
+ var list = RedisHelper.Get<IEnumerable<PddPoolDTO>>(cache_key);
|
|
|
|
|
+ if (force || list == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ lock (_lockObj)
|
|
|
|
|
+ {
|
|
|
|
|
+ list = new DBContext.Table("pdd_pool")
|
|
|
|
|
+ .Where("status=@status", new { status = 1 })
|
|
|
|
|
+ .Select<PddPoolDTO>();
|
|
|
|
|
+ if (list == null) return default;
|
|
|
|
|
+ RedisHelper.Set(cache_key, list, 30 * 86400);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ _cached = list;
|
|
|
|
|
+ return list;
|
|
|
|
|
+ }
|
|
|
|
|
+ public static void Refresh()
|
|
|
|
|
+ {
|
|
|
|
|
+ _ = List(true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void Disabled(string name)
|
|
|
|
|
+ {
|
|
|
|
|
+ string cache_key = $"cache:pdd_pool:{name}:disabled";
|
|
|
|
|
+ long count = RedisHelper.IncrBy(cache_key);
|
|
|
|
|
+ RedisHelper.Expire(cache_key, 10);
|
|
|
|
|
+ if (count > 1) return;
|
|
|
|
|
+
|
|
|
|
|
+ new DBContext.Table("pdd_pool")
|
|
|
|
|
+ .Add("status", 0)
|
|
|
|
|
+ .Where("name=@name", new { name })
|
|
|
|
|
+ .Update();
|
|
|
|
|
+ _ = List(true);
|
|
|
|
|
+
|
|
|
|
|
+ NotifyCore.Notify(new NifyMessage
|
|
|
|
|
+ {
|
|
|
|
|
+ message = $"【多多:{name}】调用异常",
|
|
|
|
|
+ priority = NifyMessagePriority.high,
|
|
|
|
|
+ tags = ["red_circle"]
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static void Disabled(int accountId, string name, string content)
|
|
|
|
|
+ {
|
|
|
|
|
+ string cache_key = $"cache:pdd_pool:{name}:disabled";
|
|
|
|
|
+ long count = RedisHelper.IncrBy(cache_key);
|
|
|
|
|
+ RedisHelper.Expire(cache_key, 10);
|
|
|
|
|
+ if (count > 1) return;
|
|
|
|
|
+
|
|
|
|
|
+ var update = new DBContext.Table("pdd_pool").Add("status", 0);
|
|
|
|
|
+ if (accountId > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ update.Where("id=@accountId", new { accountId }).Update();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ update.Where("name=@name", new { name }).Update();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _ = List(true);
|
|
|
|
|
+
|
|
|
|
|
+ NotifyCore.Notify(new NifyMessage
|
|
|
|
|
+ {
|
|
|
|
|
+ message = $"【多多{accountId}:{name}】cookie 掉线\n\n{content}",
|
|
|
|
|
+ priority = NifyMessagePriority.high,
|
|
|
|
|
+ tags = ["red_circle"]
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ NotifyCore.AnPushNotify("掉线", $"【多多{accountId}:{name}】cookie 掉线");
|
|
|
|
|
+ EndPointCore.NotifyReload(true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ internal static void AccountExhausted()
|
|
|
|
|
+ {
|
|
|
|
|
+ string cache_key = $"cache:pdd_pool:account:exhausted";
|
|
|
|
|
+ long count = RedisHelper.IncrBy(cache_key);
|
|
|
|
|
+ if (count > 1) return;
|
|
|
|
|
+ RedisHelper.Expire(cache_key, 3600);
|
|
|
|
|
+ NotifyCore.Notify(new NifyMessage
|
|
|
|
|
+ {
|
|
|
|
|
+ message = $"【多多】没有匹配账号",
|
|
|
|
|
+ priority = NifyMessagePriority.high,
|
|
|
|
|
+ tags = ["red_circle"]
|
|
|
|
|
+ });
|
|
|
|
|
+ NotifyCore.AnPushNotify("没账号", $"【多多】没有匹配账号");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static int UpdateCookies(string cookies, string user_agent)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (string.IsNullOrEmpty(cookies)) return 0;
|
|
|
|
|
+ string pin = cookies.GetContentPart("pin=", ";");
|
|
|
|
|
+ pin = pin.UrlDecode();
|
|
|
|
|
+
|
|
|
|
|
+ string company = pin;
|
|
|
|
|
+ int accountId = 0;
|
|
|
|
|
+ if (string.IsNullOrEmpty(pin)) return 0;
|
|
|
|
|
+ var exist = new DBContext.Table("pdd_pool").Get<JdPoolDTO>("pin=@pin", new { pin });
|
|
|
|
|
+ if (exist != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ var status = exist.status;
|
|
|
|
|
+ var work_mode = exist.work_mode;
|
|
|
|
|
+ accountId = exist.id;
|
|
|
|
|
+ if (work_mode == JdUnionWorkMode.Crawler) status = true;
|
|
|
|
|
+ new DBContext.Table("pdd_pool")
|
|
|
|
|
+ .Add("pin", pin)
|
|
|
|
|
+ .Add("cookies", cookies)
|
|
|
|
|
+ .Add("user_agent", user_agent)
|
|
|
|
|
+ .Add("status", status)
|
|
|
|
|
+ .Add("last_time", DateTime.Now)
|
|
|
|
|
+ .Add("login_time", DateTime.Now)
|
|
|
|
|
+ .Where("id=@id", new { exist.id })
|
|
|
|
|
+ .Update();
|
|
|
|
|
+ if (status) _ = List(true);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ accountId = new DBContext.Table("pdd_pool")
|
|
|
|
|
+ .Add("pin", pin)
|
|
|
|
|
+ .Add("name", pin)
|
|
|
|
|
+ .Add("company", pin)
|
|
|
|
|
+ .Add("description", "由cookies上报创建此记录")
|
|
|
|
|
+ .Add("cookies", cookies)
|
|
|
|
|
+ .Add("user_agent", user_agent)
|
|
|
|
|
+ .Add("create_time", DateTime.Now)
|
|
|
|
|
+ .Add("last_time", DateTime.Now)
|
|
|
|
|
+ .Add("login_time", DateTime.Now)
|
|
|
|
|
+ .Add("status", 0)
|
|
|
|
|
+ .Create();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ NotifyCore.Notify(new NifyMessage
|
|
|
|
|
+ {
|
|
|
|
|
+ message = $"【拼多多{accountId}:{company}】cookie 上线",
|
|
|
|
|
+ tags = ["green_circle"]
|
|
|
|
|
+ });
|
|
|
|
|
+ EndPointCore.NotifyReload(true);
|
|
|
|
|
+ //NotifyCore.AnPushNotify("上线", $"【淘宝联盟:{dnk}】cookie 上报更新");
|
|
|
|
|
+ return accountId;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static int Update(PddPoolDTO account)
|
|
|
|
|
+ {
|
|
|
|
|
+ return new DBContext.Table("pdd_pool")
|
|
|
|
|
+ .Add("current_hourly_calls", account.current_hourly_calls)
|
|
|
|
|
+ .Add("current_daily_calls", account.current_daily_calls)
|
|
|
|
|
+
|
|
|
|
|
+ //.Add("today_clickNum", account.today_clickNum)
|
|
|
|
|
+ //.Add("today_cosFee", account.today_cosFee)
|
|
|
|
|
+ //.Add("today_cosPrice", account.today_cosPrice)
|
|
|
|
|
+ //.Add("today_finishCosFee", account.today_finishCosFee)
|
|
|
|
|
+ //.Add("today_finishCosPrice", account.today_finishCosPrice)
|
|
|
|
|
+ //.Add("today_finishOrderNum", account.today_finishOrderNum)
|
|
|
|
|
+ //.Add("today_orderNum", account.today_orderNum)
|
|
|
|
|
+ .Where("id=@id", new { account.id })
|
|
|
|
|
+ .Update();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|