Ver Fonte

更新配置项时候通知所有节点;
统计数据时候写入到不同分配(total/parse_total/coupon_total);
reload接口调用时候,通知所有api节点;
Refresh本地缓存时 不清空当前缓存,避免缓存击穿;
oppo账号授权由原来的1天改成30天;
增加单例的redis客户端管理类;

dodo hold há 2 anos atrás
pai
commit
0b26fdd5b0
30 ficheiros alterados com 705 adições e 178 exclusões
  1. 128 69
      molilian.api/Controllers/admin/TaobaoController.cs
  2. 41 0
      molilian.api/Controllers/public/TaskController.cs
  3. 2 24
      molilian.api/Controllers/public/TkController.cs
  4. 0 0
      molilian.api/Properties/PublishProfiles/https___ccr.ccs.tencentyun.com_shaobin.pubxml.user
  5. 2 2
      molilian.core/Core/ApiAccountCore.cs
  6. 0 1
      molilian.core/Core/ConfigCore.cs
  7. 111 0
      molilian.core/Core/EndPointCore.cs
  8. 0 1
      molilian.core/Core/ProxyNodesCore.cs
  9. 0 1
      molilian.core/Core/taoke/DataokeCore.cs
  10. 0 1
      molilian.core/Core/taoke/JdPoolCore.cs
  11. 44 23
      molilian.core/Core/taoke/OrderTrackingCore.cs
  12. 0 1
      molilian.core/Core/taoke/PangolinPoolCore.cs
  13. 69 22
      molilian.core/Core/taoke/TkLogCore.cs
  14. 3 4
      molilian.core/Core/taoke/TkPoolCore.cs
  15. 10 2
      molilian.core/Core/taoke/UnionCouponCore.cs
  16. 0 1
      molilian.core/Core/taoke/VeapiPoolCore.cs
  17. 21 0
      molilian.core/DTO/EndPointDTO.cs
  18. 1 0
      molilian.core/DTO/UnionCouponDTO.cs
  19. 1 0
      molilian.core/DTO/alimama/TkDataDTO.cs
  20. 14 0
      molilian.core/DTO/alimama/TkReportDTO.cs
  21. 1 0
      molilian.core/DTO/dy/DyDataDTO.cs
  22. 1 0
      molilian.core/DTO/jd/JdDataDTO.cs
  23. 1 0
      molilian.core/DTO/tool/ToolParseDataDTO.cs
  24. 18 18
      molilian.core/Plus/Alimama/crawler.cs
  25. 9 2
      molilian.core/Plus/Alimama/parse.cs
  26. 174 6
      molilian.core/Plus/Alimama/parse_2.cs
  27. 7 0
      molilian.core/Plus/DyUnion/DyUnionPlus.cs
  28. 7 0
      molilian.core/Plus/JDUnion/JdUnionPlus.cs
  29. 33 0
      molilian.core/Plus/RedisClientManager.cs
  30. 7 0
      molilian.core/Plus/Tool/ToolParsePlus.cs

+ 128 - 69
molilian.api/Controllers/admin/TaobaoController.cs

@@ -42,7 +42,7 @@ namespace molilian.api.Controllers
                 return new APIResult(new { data = new { success = false, msg = "更新失败,请检查输入的cookie" } });
             }
 
-            int result = 0;
+            int result;
             switch (name)
             {
                 case "enable_fake_click":
@@ -59,11 +59,8 @@ namespace molilian.api.Controllers
                 default:
                     return new APIResult(new { data = new { success = false, msg = "更新失败,未授权操作" } });
             }
-
-            TkPoolCore.Refresh();
-
             bool success = result > 0;
-
+            if (success) await EndPointCore.NotifyReload(true);
             return new APIResult(new
             {
                 data = new { success, msg = success ? "更新成功" : "更新失败,请检查输入信息" },
@@ -188,7 +185,9 @@ namespace molilian.api.Controllers
             var result = new DBContext.Table("v_tk_report_dailys")
                 .LeftJoin("daily_logs",
                 "B.log_date = A.report_date AND B.accountId=@dailys_accountId",
-                "total_count, B.abandon_count, B.success_count, B.abandon_percentage, B.success_percentage")
+                "total_count, B.abandon_count, B.success_count, B.abandon_percentage, B.success_percentage," +
+                "B.parse_total_count, B.parse_abandon_count, B.parse_success_count, B.parse_abandon_percentage, B.parse_success_percentage," +
+                "B.coupon_total_count, B.coupon_abandon_count, B.coupon_success_count, B.coupon_abandon_percentage, B.coupon_success_percentage")
                 .Where(filter, new { dailys_accountId, dailys_accountName, stime, etime })
                 .Page(size, page)
                 .Order(orderBy)
@@ -198,27 +197,37 @@ namespace molilian.api.Controllers
             foreach (var item in result.List)
             {
                 if (item.total_count > 0) continue;
-                item.total_count = RedisHelper.Get<int>($":total:all:{item.report_date:yyyyMMdd}");
+                item.total_count = TkLogCore.GetTotal($":total:all:{item.report_date:yyyyMMdd}");
                 if (item.total_count == 0) continue;
-                item.success_count = RedisHelper.Get<int>($":total:all:success:{item.report_date:yyyyMMdd}");
-                item.abandon_count = RedisHelper.Get<int>($":total:all:放弃转链:{item.report_date:yyyyMMdd}");
-
-
-#if DEBUG
-                //if (item.report_date == DateTime.Now.Date)
-                //{
-                //    RedisHelper.Set($":total:all:{item.report_date:yyyyMMdd}", item.total_count / 2);
-                //    RedisHelper.Set($":total:all:success:{item.report_date:yyyyMMdd}", item.total_count / 2);
-                //    RedisHelper.Set($":total:all:放弃转链:{item.report_date:yyyyMMdd}", item.abandon_count / 2);
-                //}
-#endif
-
-
+                item.success_count = TkLogCore.GetTotal($":total:all:success:{item.report_date:yyyyMMdd}");
+                item.abandon_count = TkLogCore.GetTotal($":total:all:放弃转链:{item.report_date:yyyyMMdd}");
                 if (item.total_count > 0)
                 {
                     item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
                     item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
                 }
+
+                if (item.parse_total_count > 0) continue;
+                item.parse_total_count = TkLogCore.GetTotal($":parse_total:all:{item.report_date:yyyyMMdd}");
+                if (item.parse_total_count == 0) continue;
+                item.parse_success_count = TkLogCore.GetTotal($":parse_total:all:success:{item.report_date:yyyyMMdd}");
+                item.parse_abandon_count = TkLogCore.GetTotal($":parse_total:all:放弃转链:{item.report_date:yyyyMMdd}");
+                if (item.parse_total_count > 0)
+                {
+                    item.parse_success_percentage = $"{item.parse_success_count / (double)item.parse_total_count * 100:f2}%";
+                    item.parse_abandon_percentage = $"{item.parse_abandon_count / (double)item.parse_total_count * 100:f2}%";
+                }
+
+                if (item.coupon_total_count > 0) continue;
+                item.coupon_total_count = TkLogCore.GetTotal($":coupon_total:all:{item.report_date:yyyyMMdd}");
+                if (item.coupon_total_count == 0) continue;
+                item.coupon_success_count = TkLogCore.GetTotal($":coupon_total:all:success:{item.report_date:yyyyMMdd}");
+                item.coupon_abandon_count = TkLogCore.GetTotal($":coupon_total:all:放弃转链:{item.report_date:yyyyMMdd}");
+                if (item.coupon_total_count > 0)
+                {
+                    item.coupon_success_percentage = $"{item.coupon_success_count / (double)item.coupon_total_count * 100:f2}%";
+                    item.coupon_abandon_percentage = $"{item.coupon_abandon_count / (double)item.coupon_total_count * 100:f2}%";
+                }
             }
             return new APIResult(new { data = result });
         }
@@ -267,7 +276,9 @@ namespace molilian.api.Controllers
             var result = new DBContext.Table("tk_report")
                 .LeftJoin("daily_logs",
                 "B.log_date = A.report_date AND B.accountId=A.accountId",
-                "total_count, B.abandon_count, B.success_count, B.abandon_percentage, B.success_percentage")
+                "total_count, B.abandon_count, B.success_count, B.abandon_percentage, B.success_percentage," +
+                "B.parse_total_count, B.parse_abandon_count, B.parse_success_count, B.parse_abandon_percentage, B.parse_success_percentage," +
+                "B.coupon_total_count, B.coupon_abandon_count, B.coupon_success_count, B.coupon_abandon_percentage, B.coupon_success_percentage")
                 .Where(filter, new { accountId, stime, etime })
                 .Page(size, page)
                 .Order(orderBy)
@@ -279,33 +290,56 @@ namespace molilian.api.Controllers
             {
                 //var tk = TkPoolCore.GetOne(item.accountId);
                 //if (tk != null) item.accountName = tk.company;
-
-                if (item.total_count > 0) continue;
-
                 string accountName = $"{TkChannelEnum.tb}_{item.accountId}";
 
-                item.total_count = RedisHelper.Get<int>($":total:{accountName}:{item.report_date:yyyyMMdd}");
                 if (item.total_count == 0)
                 {
-                    //todo  过度用, 0613 跑两天就可以删掉
-                    accountName = item.accountName;
-                    item.total_count = RedisHelper.Get<int>($":total:{accountName}:{item.report_date:yyyyMMdd}");
+                    item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMdd}");
+                    if (item.total_count == 0)
+                    {
+                        //todo  过度用, 0613 跑两天就可以删掉
+                        accountName = item.accountName;
+                        item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMdd}");
+                    }
+                    if (item.total_count == 0) continue;
+                    item.success_count = TkLogCore.GetTotal($":total:{accountName}:success:{item.report_date:yyyyMMdd}");
+                    item.abandon_count = TkLogCore.GetTotal($":total:{accountName}:放弃转链:{item.report_date:yyyyMMdd}");
+
+                    if (item.total_count > 0)
+                    {
+                        item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
+                        item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
+                    }
                 }
-                if (item.total_count == 0) continue;
-                item.success_count = RedisHelper.Get<int>($":total:{accountName}:success:{item.report_date:yyyyMMdd}");
-                item.abandon_count = RedisHelper.Get<int>($":total:{accountName}:放弃转链:{item.report_date:yyyyMMdd}");
 
-                if (item.total_count > 0)
+                if (item.parse_total_count == 0)
                 {
-                    item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
-                    item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
+                    item.parse_total_count = TkLogCore.GetTotal($":parse_total:{accountName}:{item.report_date:yyyyMMdd}");
+                    if (item.parse_total_count == 0) continue;
+                    item.parse_success_count = TkLogCore.GetTotal($":parse_total:{accountName}:success:{item.report_date:yyyyMMdd}");
+                    item.parse_abandon_count = TkLogCore.GetTotal($":parse_total:{accountName}:放弃转链:{item.report_date:yyyyMMdd}");
+
+                    if (item.parse_total_count > 0)
+                    {
+                        item.parse_success_percentage = $"{item.parse_success_count / (double)item.parse_total_count * 100:f2}%";
+                        item.parse_abandon_percentage = $"{item.parse_abandon_count / (double)item.parse_total_count * 100:f2}%";
+                    }
                 }
-            }
-
 
-            //public int api_req_num { get; set; } = 0;
-            //public int abandon_num { get; set; } = 0;
-            //public int success_num { get; set; } = 0;
+                if (item.coupon_total_count == 0)
+                {
+                    item.coupon_total_count = TkLogCore.GetTotal($":coupon_total:{accountName}:{item.report_date:yyyyMMdd}");
+                    if (item.coupon_total_count == 0) continue;
+                    item.coupon_success_count = TkLogCore.GetTotal($":coupon_total:{accountName}:success:{item.report_date:yyyyMMdd}");
+                    item.coupon_abandon_count = TkLogCore.GetTotal($":coupon_total:{accountName}:放弃转链:{item.report_date:yyyyMMdd}");
+
+                    if (item.coupon_total_count > 0)
+                    {
+                        item.coupon_success_percentage = $"{item.coupon_success_count / (double)item.coupon_total_count * 100:f2}%";
+                        item.coupon_abandon_percentage = $"{item.coupon_abandon_count / (double)item.coupon_total_count * 100:f2}%";
+                    }
+                }
+            }
             return new APIResult(new { data = result });
         }
 
@@ -360,24 +394,54 @@ namespace molilian.api.Controllers
 
             foreach (var item in result.List)
             {
-                if (item.total_count > 0) continue;
-
                 string accountName = $"{TkChannelEnum.tb}_{item.accountId}";
-                item.total_count = RedisHelper.Get<int>($":total:{accountName}:{item.report_date:yyyyMMddHH}");
                 if (item.total_count == 0)
                 {
-                    //todo  过度用, 0613 跑两天就可以删掉
-                    accountName = item.accountName;
-                    item.total_count = RedisHelper.Get<int>($":total:{accountName}:{item.report_date:yyyyMMddHH}");
+                    item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMddHH}");
+                    if (item.total_count == 0)
+                    {
+                        //todo  过度用, 0613 跑两天就可以删掉
+                        accountName = item.accountName;
+                        item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMddHH}");
+                    }
+                    if (item.total_count == 0) continue;
+                    item.success_count = TkLogCore.GetTotal($":total:{item.accountName}:success:{item.report_date:yyyyMMddHH}");
+                    item.abandon_count = TkLogCore.GetTotal($":total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}");
+
+                    if (item.total_count > 0)
+                    {
+                        item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
+                        item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
+                    }
                 }
-                if (item.total_count == 0) continue;
-                item.success_count = RedisHelper.Get<int>($":total:{item.accountName}:success:{item.report_date:yyyyMMddHH}");
-                item.abandon_count = RedisHelper.Get<int>($":total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}");
 
-                if (item.total_count > 0)
+                if (item.parse_total_count == 0)
                 {
-                    item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
-                    item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
+                    item.parse_total_count = TkLogCore.GetTotal($":parse_total:{accountName}:{item.report_date:yyyyMMddHH}");
+                    if (item.parse_total_count == 0) continue;
+                    item.parse_success_count = TkLogCore.GetTotal($":parse_total:{item.accountName}:success:{item.report_date:yyyyMMddHH}");
+                    item.parse_abandon_count = TkLogCore.GetTotal($":parse_total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}");
+
+                    if (item.parse_total_count > 0)
+                    {
+                        item.parse_success_percentage = $"{item.parse_success_count / (double)item.parse_total_count * 100:f2}%";
+                        item.parse_abandon_percentage = $"{item.parse_abandon_count / (double)item.parse_total_count * 100:f2}%";
+                    }
+                }
+
+                if (item.coupon_total_count == 0)
+                {
+                    item.coupon_total_count = TkLogCore.GetTotal($":coupon_total:{accountName}:{item.report_date:yyyyMMddHH}");
+               
+                    if (item.coupon_total_count == 0) continue;
+                    item.coupon_success_count = TkLogCore.GetTotal($":coupon_total:{item.accountName}:success:{item.report_date:yyyyMMddHH}");
+                    item.coupon_abandon_count = TkLogCore.GetTotal($":coupon_total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}");
+
+                    if (item.coupon_total_count > 0)
+                    {
+                        item.coupon_success_percentage = $"{item.coupon_success_count / (double)item.coupon_total_count * 100:f2}%";
+                        item.coupon_abandon_percentage = $"{item.coupon_abandon_count / (double)item.coupon_total_count * 100:f2}%";
+                    }
                 }
             }
             return new APIResult(new { data = result });
@@ -393,6 +457,7 @@ namespace molilian.api.Controllers
             var report_date = form.PathReadArray<string>("query_date[]");
             var accountName = form.Read("accountName", string.Empty);
             var isHourtrend = form.Read<bool>("isLeaf", false);
+            var total_key = form.Read("total_key", "total");
 
             if (string.IsNullOrEmpty(accountName)) accountName = "all";
 
@@ -402,39 +467,33 @@ namespace molilian.api.Controllers
             string _report_date = stime.ToString("yyyyMMdd");
             if (isHourtrend) _report_date = stime.ToString("yyyyMMddHH");
 
-            string cacheKey = $":total:{accountName}:{_report_date}";
-            double total = RedisHelper.Get<int>(cacheKey);
+            string cacheKey = $":{total_key}:{accountName}:{_report_date}";
+            double total = TkLogCore.GetTotal(cacheKey);
             if (total > 0)
             {
-                string[] keys = new string[] { "success" };
-                cacheKey = $":total:{accountName}:message:{_report_date}";
-                string[] message_keys = RedisHelper.SMembers(cacheKey);
+                string[] keys = ["success"];
+                cacheKey = $":{total_key}:{accountName}:message:{_report_date}";
+                string[] message_keys = TkLogCore.GetTotalKeys(cacheKey);
 
                 string[] combinedKeys = keys.Union(message_keys).ToArray();
 
                 foreach (var keyname in combinedKeys)
                 {
-                    cacheKey = $":total:{accountName}:{keyname}:{_report_date}";
-                    int value = RedisHelper.Get<int>(cacheKey);
+                    cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
                     if (value == 0) continue;
-#if DEBUG
-                    //RedisHelper.Set(cacheKey, value / 2);
-#endif
                     result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
                 }
                 result = result.OrderByDescending(item => item.value).ToList();
 
-                cacheKey = $":total:{accountName}:reason:{_report_date}";
-                string[] reason_keys = RedisHelper.SMembers(cacheKey);
+                cacheKey = $":{total_key}:{accountName}:reason:{_report_date}";
+                string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);
 
                 foreach (var keyname in reason_keys)
                 {
-                    cacheKey = $":total:{accountName}:{keyname}:{_report_date}";
-                    int value = RedisHelper.Get<int>(cacheKey);
+                    cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
                     if (value == 0) continue;
-#if DEBUG
-                    //RedisHelper.Set(cacheKey, value / 2);
-#endif
                     reason_result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
                 }
                 reason_result = reason_result.OrderByDescending(item => item.value).ToList();

+ 41 - 0
molilian.api/Controllers/public/TaskController.cs

@@ -165,6 +165,8 @@ namespace molilian.api.Controllers
             try
             {
                 AlimamaPlus.DailyLogs(intervalDay);
+                AlimamaPlus.DailyLogs(intervalDay, "parse_");
+                AlimamaPlus.DailyLogs(intervalDay, "coupon_");
             }
             catch (Exception ex)
             {
@@ -330,5 +332,44 @@ namespace molilian.api.Controllers
             (bool success, string message) = alimama.RenewCookie();
             return new APIResult(new { success, message });
         }
+
+
+        [HttpGet]
+        public ActionResult Reload()
+        {
+            TkConfigCore.Refresh();
+            EndPointCore.Refresh();
+            ProxyNodesCore.Refresh();
+            TkPoolCore.Refresh();
+            VeapiPoolCore.Refresh();
+
+            ApiAccountCore.Refresh();
+            DataokeCore.Refresh();
+            JdPoolCore.Refresh();
+            PangolinPoolCore.Refresh();
+
+            return new APIResult(new
+            {
+                success = true,
+                message = "ok",
+            });
+        }
+
+        [HttpGet]
+        public ActionResult ReloadAccount()
+        {
+            EndPointCore.Refresh();
+            ProxyNodesCore.Refresh();
+            TkPoolCore.Refresh();
+            VeapiPoolCore.Refresh();
+
+            return new APIResult(new
+            {
+                success = true,
+                message = "ok",
+            });
+        }
+
+
     }
 }

+ 2 - 24
molilian.api/Controllers/public/TkController.cs

@@ -555,17 +555,9 @@ namespace molilian.api.Controllers
 
 
         [HttpGet]
-        public ActionResult reload()
+        public async Task<ActionResult> Reload()
         {
-            ApiAccountCore.Refresh();
-            ProxyNodesCore.Refresh();
-            DataokeCore.Refresh();
-            JdPoolCore.Refresh();
-            PangolinPoolCore.Refresh();
-
-            TkConfigCore.Refresh();
-            TkPoolCore.Refresh();
-            VeapiPoolCore.Refresh();
+            await EndPointCore.NotifyReload();
             return new APIResult(new
             {
                 success = true,
@@ -573,20 +565,6 @@ namespace molilian.api.Controllers
             });
         }
 
-        [HttpPost]
-        public ActionResult updateCookies([FromBody] JsonElement form)
-        {
-            string cookie = form.Read<string>("cookie", string.Empty);
-            var user_agent = _accessor.HttpContext.Request.UserAgent();
-            TkPoolCore.UpdateCookies(cookie, user_agent);
-            return new APIResult(new
-            {
-                success = true,
-                message = "ok"
-            });
-        }
-
-
 
         [HttpGet]
         public async Task<ActionResult> dplist([FromQuery] string query = "", [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
molilian.api/Properties/PublishProfiles/https___ccr.ccs.tencentyun.com_shaobin.pubxml.user


+ 2 - 2
molilian.core/Core/ApiAccountCore.cs

@@ -48,7 +48,7 @@ namespace molilian.core
                 {
                     list = new DBContext.Table("api_account").Select<ApiAccountDTO>();
                     if (list == null) return default;
-                    RedisHelper.Set(cache_key, list, 1 * 86400);
+                    RedisHelper.Set(cache_key, list, 30 * 86400);
                 }
             }
             _cached = list;
@@ -56,7 +56,6 @@ namespace molilian.core
         }
         public static void Refresh()
         {
-            _cached = null;
             _ = List(true);
         }
 
@@ -72,6 +71,7 @@ namespace molilian.core
                 .Where("name=@name", new { name })
                 .Update();
             _ = List(true);
+            EndPointCore.NotifyReload();
         }
 
 

+ 0 - 1
molilian.core/Core/ConfigCore.cs

@@ -57,7 +57,6 @@ namespace molilian.core
 
         public static void Refresh()
         {
-            _cached = null;
             _ = Get(true);
         }
 

+ 111 - 0
molilian.core/Core/EndPointCore.cs

@@ -0,0 +1,111 @@
+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 Spire.Pdf.Exporting.XPS.Schema;
+using System.Xml.Linq;
+using System.Net;
+using TencentCloud.Mrs.V20200910.Models;
+using static molilian.core.TkPoolCore;
+using Org.BouncyCastle.Tls;
+
+
+namespace molilian.core
+{
+    public partial class EndPointCore
+    {
+        private static readonly object _lockObj = new();
+        private static IEnumerable<EndPointDTO> _cached;
+        public static EndPointDTO GetOne(string node)
+        {
+            var list = List();
+            if (!list.Any()) return null;
+            var item = list.Where(s => s.name == node).FirstOrDefault();
+            return item;
+        }
+
+        public static IEnumerable<EndPointDTO> List(bool force = false)
+        {
+            if (!force && _cached != null) return _cached;
+
+            string cache_key = $"cache:end_point";
+            var list = RedisHelper.Get<IEnumerable<EndPointDTO>>(cache_key);
+            if (force || list == null)
+            {
+                lock (_lockObj)
+                {
+                    list = new DBContext.Table("end_point")
+                        .Where("status=@status", new { status = 1 })
+                        .Select<EndPointDTO>();
+                    if (list == null) return default;
+                    RedisHelper.Set(cache_key, list, 30 * 86400);
+                }
+            }
+            _cached = list;
+            return list;
+        }
+        public static void Refresh()
+        {
+            _ = List(true);
+        }
+
+        public static List<T> ProcessEndPointNodes<T>(Func<EndPointDTO, T> nodeAction, bool force = false)
+        {
+            var resultList = new List<T>();
+            var list = List(force);
+            foreach (var node in list)
+            {
+                var result = nodeAction(node);
+                if (result != null) resultList.Add(result);
+            }
+            return resultList;
+        }
+
+
+
+
+        public static async Task ProcessEndPointNodesAsync(Func<EndPointDTO, Task> nodeAction, bool force = false)
+        {
+            var list = List(force);
+            var tasks = new List<Task>();
+            foreach (var node in list)
+            {
+                tasks.Add(nodeAction(node));
+            }
+            await Task.WhenAll(tasks);
+        }
+
+        public static async Task NotifyReload(bool onlyAccount = false)
+        {
+            await ProcessEndPointNodesAsync(async node =>
+            {
+                try
+                {
+                    string url = $"{node.api_server}Task_70160bd632/reload";
+                    if (onlyAccount) url = $"{node.api_server}Task_70160bd632/reloadAccount";
+                    await new WebClientUtility().RequestAsync(url);
+                }
+                catch (Exception ex)
+                {
+                    _ = new LoggerLibrary("NotifyReload", "error")
+                    .Info(node.Convert2Json())
+                    .Info(ex.Message, ex.StackTrace)
+                    .SaveAsync();
+
+                    NotifyCore.Notify(new NifyMessage
+                    {
+                        message = $"【NotifyReload异常】{node.description}\n{ex.Message}\n{ex.StackTrace}",
+                        priority = NifyMessagePriority.high,
+                        tags = ["red_circle"]
+                    });
+                }
+            });
+        }
+
+    }
+
+}

+ 0 - 1
molilian.core/Core/ProxyNodesCore.cs

@@ -73,7 +73,6 @@ namespace molilian.core
         }
         public static void Refresh()
         {
-            _cached = null;
             _ = List(true);
         }
 

+ 0 - 1
molilian.core/Core/taoke/DataokeCore.cs

@@ -48,7 +48,6 @@ namespace molilian.core
         }
         public static void Refresh()
         {
-            _cached = null;
             _ = List(true);
         }
 

+ 0 - 1
molilian.core/Core/taoke/JdPoolCore.cs

@@ -44,7 +44,6 @@ namespace molilian.core
         }
         public static void Refresh()
         {
-            _cached = null;
             _ = List(true);
         }
 

+ 44 - 23
molilian.core/Core/taoke/OrderTrackingCore.cs

@@ -13,6 +13,7 @@ using System.Text.Json;
 using TencentCloud.Tcm.V20210413.Models;
 using System.Security.Cryptography;
 using System.Data;
+using System.Threading.Channels;
 
 
 namespace molilian.core
@@ -21,35 +22,59 @@ namespace molilian.core
     {
         public static void SaveLinkSummary(TkDataDTO item)
         {
+            //清洗数据
+            item.content = null;
+            item.rawContent = null;
+            item.rawContent2 = null;
+
+            TkDataDTO newData = new()
+            {
+                channel = item.channel,
+                ip = item.ip,
+                oaid = item.oaid,
+                itemId = item.itemId,
+                itemName = item.itemName,
+                taoToken = item.taoToken,
+                shortLinkurl = item.shortLinkurl,
+                deeplink_url = item.deeplink_url,
+                create_time = item.create_time,
+            };
+
             var config = TkConfigCore.Get();
             var ttl = config.fake_click_ttl * 3600;
             string cacheKey = $":cache:order_summary:{item.accountId}:{item.itemId}";
-            RedisHelper.Set(cacheKey, item, ttl);
+            RedisHelper.Set(cacheKey, newData, ttl);
 
             cacheKey = $":cache:order_summary:{item.accountId}:{item.itemName}";
-            RedisHelper.Set(cacheKey, item, ttl);
-        }
-        //过时待删
-        public static TkDataDTO GetLinkSummary(string accountName, string name)
-        {
-            string cacheKey = $":cache:order_summary:{accountName}:{name}";
-            return RedisHelper.Get<TkDataDTO>(cacheKey);
-        }
-        //过时待删
-        public static void RemoveLinkSummary(string accountName, string itemId)
-        {
-            string cacheKey = $":cache:order_summary:{accountName}:{itemId}";
-            RedisHelper.Del(cacheKey);
+            RedisHelper.Set(cacheKey, newData, ttl);
         }
+
         public static TkDataDTO GetLinkSummary(int accountId, string name)
         {
             string cacheKey = $":cache:order_summary:{accountId}:{name}";
-            return RedisHelper.Get<TkDataDTO>(cacheKey);
+            var result = EndPointCore.ProcessEndPointNodes<TkDataDTO>(node =>
+            {
+                if (!node.is_public_api) return null;
+
+                var redis = RedisClientManager.GetRedisClient(node.redis_server);
+                var result = redis.Get<TkDataDTO>(cacheKey);
+                if (result != null) return result;
+                return null;
+            });
+            return result.Count > 0 ? result[0] : null;
         }
-        public static void RemoveLinkSummary(int accountId, string itemId)
+
+        public static async void RemoveLinkSummary(int accountId, string itemId)
         {
             string cacheKey = $":cache:order_summary:{accountId}:{itemId}";
-            RedisHelper.Del(cacheKey);
+            await EndPointCore.ProcessEndPointNodesAsync(node =>
+            {
+                if (!node.is_public_api) return Task.CompletedTask;
+
+                var redis = RedisClientManager.GetRedisClient(node.redis_server);
+                redis.Del(cacheKey);
+                return Task.CompletedTask;
+            });
         }
 
         public static bool MatchOrder(TkOrderDetailDTO item, IDbConnection conn)
@@ -57,11 +82,8 @@ namespace molilian.core
             if (item.tbPaidTime < DateTime.Now.AddDays(-1)) return false;
 
             var summary = GetLinkSummary(item.accountId, item.itemTitle);
-            if (summary == null)
-            {
-                summary = GetLinkSummary(item.accountName, item.itemTitle);
-                if (summary == null) return false;
-            }
+            if (summary == null) return false;
+
 
             var config = TkConfigCore.Get();
             Random rand = new();
@@ -104,7 +126,6 @@ namespace molilian.core
 
             conn.Replace(data);
             RemoveLinkSummary(item.accountId, item.itemTitle);
-            RemoveLinkSummary(item.accountName, item.itemTitle);
             return true;
         }
     }

+ 0 - 1
molilian.core/Core/taoke/PangolinPoolCore.cs

@@ -48,7 +48,6 @@ namespace molilian.core
         }
         public static void Refresh()
         {
-            _cached = null;
             _ = List(true);
         }
 

+ 69 - 22
molilian.core/Core/taoke/TkLogCore.cs

@@ -12,6 +12,8 @@ using System.Security.Cryptography;
 using Spire.Pdf.Exporting.XPS.Schema;
 using System.Xml.Linq;
 using static QRCoder.PayloadGenerator;
+using TencentCloud.Ssl.V20191205.Models;
+using CSRedis;
 
 
 namespace molilian.core
@@ -29,6 +31,18 @@ namespace molilian.core
         static string queue_coupon_key = "queue:coupon_logs";
 
         public static int BatchInsertLogDB(int limit)
+        {
+            var result = EndPointCore.ProcessEndPointNodes<int>(node =>
+            {
+                if (!node.is_public_api) return 0;
+                var redis = RedisClientManager.GetRedisClient(node.redis_server);
+                return BatchInsertLogDB(limit, redis);
+            });
+            return result.Sum();
+        }
+
+
+        public static int BatchInsertLogDB(int limit, CSRedisClient redis)
         {
             int total = 0;
             using var connection = DBContext.GetOpenConnection();
@@ -38,9 +52,10 @@ namespace molilian.core
             {
                 for (int i = 0; i < limit; i++)
                 {
-                    var data = RedisHelper.LPop<TkDataDTO>(queue_tb_key);
+                    var data = redis.LPop<TkDataDTO>(queue_tb_key);
                     if (data == null) break;
                     data.id = new DBContext.Table(connection, "tk_logs")
+                        .Add("end_point", data.end_point)
                         .Add("channel", (int)data.channel)
                         .Add("accountId", data.accountId)
                         .Add("accountName", data.accountName)
@@ -70,33 +85,35 @@ namespace molilian.core
 
                 for (int i = 0; i < limit; i++)
                 {
-                    var data = RedisHelper.LPop<JdDataDTO>(queue_jd_key);
+                    var data = redis.LPop<JdDataDTO>(queue_jd_key);
                     if (data == null) break;
                     new DBContext.Table(connection, "tk_logs")
-                       .Add("channel", (int)data.channel)
-                       .Add("accountId", data.accountId)
-                       .Add("accountName", data.accountName)
-                       .Add("rawContent", data.rawContent)
-                       .Add("rawContent2", data.rawContent2)
-                       .Add("success", data.success)
-                       .Add("message", data.message)
-                       .Add("reason", data.reason)
-                       .Add("shortLinkurl", data.shortLinkurl)
-                       .Add("deeplink_url", data.deeplink_url)
-                       .Add("elapsedTime", data.elapsedTime)
-                       .Add("ip", data.ip)
-                       .Add("oaid", data.oaid)
-                       .Add("create_time", data.create_time)
-                       .Create(DBContext.InsertType.NORMAL, transaction);
+                        .Add("end_point", data.end_point)
+                        .Add("channel", (int)data.channel)
+                        .Add("accountId", data.accountId)
+                        .Add("accountName", data.accountName)
+                        .Add("rawContent", data.rawContent)
+                        .Add("rawContent2", data.rawContent2)
+                        .Add("success", data.success)
+                        .Add("message", data.message)
+                        .Add("reason", data.reason)
+                        .Add("shortLinkurl", data.shortLinkurl)
+                        .Add("deeplink_url", data.deeplink_url)
+                        .Add("elapsedTime", data.elapsedTime)
+                        .Add("ip", data.ip)
+                        .Add("oaid", data.oaid)
+                        .Add("create_time", data.create_time)
+                        .Create(DBContext.InsertType.NORMAL, transaction);
                     total++;
                 }
 
                 for (int i = 0; i < limit; i++)
                 {
-                    var data = RedisHelper.LPop<TkDataDTO>(queue_parse_tb_key);
+                    var data = redis.LPop<TkDataDTO>(queue_parse_tb_key);
                     if (data == null) break;
 
                     data.id = new DBContext.Table(connection, "tk_parse_logs")
+                        .Add("end_point", data.end_point)
                         .Add("channel", (int)data.channel)
                         .Add("accountId", data.accountId)
                         .Add("accountName", data.accountName)
@@ -127,9 +144,10 @@ namespace molilian.core
 
                 for (int i = 0; i < limit; i++)
                 {
-                    var data = RedisHelper.LPop<JdDataDTO>(queue_parse_jd_key);
+                    var data = redis.LPop<JdDataDTO>(queue_parse_jd_key);
                     if (data == null) break;
                     new DBContext.Table(connection, "tk_parse_logs")
+                        .Add("end_point", data.end_point)
                         .Add("channel", (int)data.channel)
                         .Add("accountId", data.accountId)
                         .Add("accountName", data.accountName)
@@ -155,9 +173,10 @@ namespace molilian.core
                 }
                 for (int i = 0; i < limit; i++)
                 {
-                    var data = RedisHelper.LPop<DyDataDTO>(queue_parse_dy_key);
+                    var data = redis.LPop<DyDataDTO>(queue_parse_dy_key);
                     if (data == null) break;
                     new DBContext.Table(connection, "tk_parse_logs")
+                        .Add("end_point", data.end_point)
                         .Add("channel", (int)data.channel)
                         .Add("accountId", data.accountId)
                         .Add("accountName", data.accountName)
@@ -183,9 +202,10 @@ namespace molilian.core
                 }
                 for (int i = 0; i < limit; i++)
                 {
-                    var data = RedisHelper.LPop<ToolParseDataDTO>(queue_parse_tool_key);
+                    var data = redis.LPop<ToolParseDataDTO>(queue_parse_tool_key);
                     if (data == null) break;
                     new DBContext.Table(connection, "tool_parse_logs")
+                        .Add("end_point", data.end_point)
                         .Add("channel", (int)data.channel)
                         .Add("rawContent", data.rawContent)
                         .Add("success", data.success)
@@ -206,7 +226,7 @@ namespace molilian.core
 
                 for (int i = 0; i < limit; i++)
                 {
-                    var data = RedisHelper.LPop<UnionCouponDTO>(queue_coupon_key);
+                    var data = redis.LPop<UnionCouponDTO>(queue_coupon_key);
                     if (data == null) break;
                     connection.Insert(data);
                     total++;
@@ -544,6 +564,33 @@ namespace molilian.core
 
         }
 
+        public static int GetTotal(string keyname, bool all_node = true)
+        {
+            int result = RedisHelper.Get<int>(keyname);
+            return result;
+        }
+
+        public static string[] GetTotalKeys(string keyname, bool all_node = true)
+        {
+            string[] message_keys = RedisHelper.SMembers(keyname);
+            return message_keys;
+
+            //string[] message_keys2 = RedisHelper.SMembers(keyname.Replace(":total:", ":parse_total:"));
+            //message_keys = message_keys.Union(message_keys2).ToArray();
+
+            //string[] message_keys3 = RedisHelper.SMembers(keyname.Replace(":total:", ":coupon_total:"));
+            //message_keys = message_keys.Union(message_keys3).ToArray();
+        }
+
+
+        //if (item.total_count > 0) continue;
+        //item.total_count = RedisHelper.Get<int>($":total:all:{item.report_date:yyyyMMdd}");
+        //if (item.total_count == 0) continue;
+        //item.success_count = RedisHelper.Get<int>($":total:all:success:{item.report_date:yyyyMMdd}");
+        //item.abandon_count = RedisHelper.Get<int>($":total:all:放弃转链:{item.report_date:yyyyMMdd}");
+
+
+
 
     }
 

+ 3 - 4
molilian.core/Core/taoke/TkPoolCore.cs

@@ -115,7 +115,6 @@ namespace molilian.core
         }
         public static void Refresh()
         {
-            _cached = null;
             _incomeAmt = [];
             _ = List(true);
         }
@@ -132,6 +131,7 @@ namespace molilian.core
         {
 #if DEBUG
 #else
+#endif
             string cache_key = $"cache:tk_pool:{name}:disabled";
             long count = RedisHelper.IncrBy(cache_key);
             RedisHelper.Expire(cache_key, 10);
@@ -151,8 +151,7 @@ namespace molilian.core
             });
 
             NotifyCore.AnPushNotify("掉线", $"【淘宝联盟:{name}】cookie 掉线");
-
-#endif
+            EndPointCore.NotifyReload(true);
         }
 
         public static bool UpdateCookies(string cookies, string user_agent)
@@ -199,8 +198,8 @@ namespace molilian.core
                 message = $"【淘宝联盟:{dnk}】cookie 上线",
                 tags = ["green_circle"]
             });
+            EndPointCore.NotifyReload(true);
             //NotifyCore.AnPushNotify("上线", $"【淘宝联盟:{dnk}】cookie 上报更新");
-
             return true;
         }
 

+ 10 - 2
molilian.core/Core/taoke/UnionCouponCore.cs

@@ -23,6 +23,12 @@ namespace molilian.core
     public partial class UnionCouponCore
     {
 
+        private static string _end_point;
+        static UnionCouponCore()
+        {
+            _end_point = Environment.GetEnvironmentVariable("EndPoint");
+        }
+
         public static async Task<ActionResult> UnionCouponAsync(string content, string channel, string ip, string oaid)
         {
             return channel switch
@@ -39,7 +45,8 @@ namespace molilian.core
             UnionCouponDTO result = new()
             {
                 channel = TkChannelEnum.tb,
-                rawContent = content
+                rawContent = content,
+                end_point = _end_point,
             };
             try
             {
@@ -141,7 +148,8 @@ namespace molilian.core
             UnionCouponDTO result = new()
             {
                 channel = TkChannelEnum.jd,
-                rawContent = content
+                rawContent = content,
+                end_point = _end_point,
             };
 
             try

+ 0 - 1
molilian.core/Core/taoke/VeapiPoolCore.cs

@@ -48,7 +48,6 @@ namespace molilian.core
         }
         public static void Refresh()
         {
-            _cached = null;
             _ = List(true);
         }
 

+ 21 - 0
molilian.core/DTO/EndPointDTO.cs

@@ -0,0 +1,21 @@
+using System.Xml.Linq;
+using TencentCloud.Ame.V20190916.Models;
+using TencentCloud.Mrs.V20200910.Models;
+
+namespace molilian.core
+{
+    public class EndPointDTO
+    {
+        public int id { get; set; } 
+        public string name { get; set; } = string.Empty;
+        public string description { get; set; } = string.Empty;
+        public string redis_server { get; set; } = string.Empty;
+
+        public string api_server { get; set; } = string.Empty;
+        public DateTime create_time { get; set; }
+        public DateTime last_time { get; set; }
+        public bool status { get; set; } = false;
+        public bool is_public_api { get; set; } = false;
+
+    }
+}

+ 1 - 0
molilian.core/DTO/UnionCouponDTO.cs

@@ -25,5 +25,6 @@ namespace molilian.core
         public DateTime create_time { get; set; } = DateTime.Now;
         public string couponEffectiveStartTime { get; set; } = string.Empty;
         public string couponEffectiveEndTime { get; set; } = string.Empty;
+        public string end_point { get; set; } = string.Empty;
     }
 }

+ 1 - 0
molilian.core/DTO/alimama/TkDataDTO.cs

@@ -44,6 +44,7 @@ namespace molilian.core
         public string couponEffectiveStartTime { get; set; } = string.Empty;
         [IgnoreInsert, IgnoreUpdate]
         public string couponEffectiveEndTime { get; set; } = string.Empty;
+        public string end_point { get; set; } = string.Empty;
 
     }
 

+ 14 - 0
molilian.core/DTO/alimama/TkReportDTO.cs

@@ -123,6 +123,20 @@
         public string abandon_percentage { get; set; } = string.Empty;
         public string success_percentage { get; set; } = string.Empty;
 
+
+        public int parse_total_count { get; set; } = 0;
+        public int parse_abandon_count { get; set; } = 0;
+        public int parse_success_count { get; set; } = 0;
+        public string parse_abandon_percentage { get; set; } = string.Empty;
+        public string parse_success_percentage { get; set; } = string.Empty;
+
+
+        public int coupon_total_count { get; set; } = 0;
+        public int coupon_abandon_count { get; set; } = 0;
+        public int coupon_success_count { get; set; } = 0;
+        public string coupon_abandon_percentage { get; set; } = string.Empty;
+        public string coupon_success_percentage { get; set; } = string.Empty;
+
     }
 
 }

+ 1 - 0
molilian.core/DTO/dy/DyDataDTO.cs

@@ -27,5 +27,6 @@
         public string deeplink_url { get; set; } = string.Empty;
         public int elapsedTime { get; set; } = 0;
         public DateTime create_time { get; set; } = DateTime.Now;
+        public string end_point { get; set; } = string.Empty;
     }
 }

+ 1 - 0
molilian.core/DTO/jd/JdDataDTO.cs

@@ -27,6 +27,7 @@
         public string deeplink_url { get; set; } = string.Empty;
         public int elapsedTime { get; set; } = 0;
         public DateTime create_time { get; set; } = DateTime.Now;
+        public string end_point { get; set; } = string.Empty;
     }
 
 }

+ 1 - 0
molilian.core/DTO/tool/ToolParseDataDTO.cs

@@ -16,6 +16,7 @@
         public string itemName { get; set; } = string.Empty;
         public int elapsedTime { get; set; } = 0;
         public DateTime create_time { get; set; } = DateTime.Now;
+        public string end_point { get; set; } = string.Empty;
     }
 
 }

+ 18 - 18
molilian.core/Plus/Alimama/crawler.cs

@@ -29,7 +29,7 @@ namespace molilian.core
         /// 更新API调用日志(1天一次)
         /// </summary>
         /// <param name="intervalDay"></param>
-        public static void DailyLogs(int intervalDay)
+        public static void DailyLogs(int intervalDay, string prefix = "")
         {
 
             DateTime log_date = DateTime.Now.AddDays(-intervalDay).Date;
@@ -41,14 +41,14 @@ namespace molilian.core
                 int accountId = account.id;
                 string accountName = $"{TkChannelEnum.tb}_{account.id}";
 
-                int total_count = RedisHelper.Get<int>($":total:{accountName}:{log_date:yyyyMMdd}");
+                int total_count = TkLogCore.GetTotal($":{prefix}total:{accountName}:{log_date:yyyyMMdd}");
                 if (total_count == 0) accountName = account.name;
 
-                total_count = RedisHelper.Get<int>($":total:{accountName}:{log_date:yyyyMMdd}");
+                total_count = TkLogCore.GetTotal($":{prefix}total:{accountName}:{log_date:yyyyMMdd}");
                 if (total_count == 0) continue;
 
-                var success_count = RedisHelper.Get<int>($":total:{accountName}:success:{log_date:yyyyMMdd}");
-                var abandon_count = RedisHelper.Get<int>($":total:{accountName}:放弃转链:{log_date:yyyyMMdd}");
+                var success_count = TkLogCore.GetTotal($":{prefix}total:{accountName}:success:{log_date:yyyyMMdd}");
+                var abandon_count = TkLogCore.GetTotal($":{prefix}total:{accountName}:放弃转链:{log_date:yyyyMMdd}");
                 string success_percentage = string.Empty;
                 string abandon_percentage = string.Empty;
 
@@ -64,11 +64,11 @@ namespace molilian.core
 
                 var createArgs = new DBContext.Table("daily_logs")
 
-                    .Add("total_count", total_count)
-                    .Add("abandon_count", abandon_count)
-                    .Add("abandon_percentage", abandon_percentage)
-                    .Add("success_count", success_count)
-                    .Add("success_percentage", success_percentage)
+                    .Add($"{prefix}total_count", total_count)
+                    .Add($"{prefix}abandon_count", abandon_count)
+                    .Add($"{prefix}abandon_percentage", abandon_percentage)
+                    .Add($"{prefix}success_count", success_count)
+                    .Add($"{prefix}success_percentage", success_percentage)
                     .Add("last_time", DateTime.Now);
 
                 if (exist == null)
@@ -87,9 +87,9 @@ namespace molilian.core
             }
 
 
-            int all_total_count = RedisHelper.Get<int>($":total:all:{log_date:yyyyMMdd}");
-            var all_success_count = RedisHelper.Get<int>($":total:all:success:{log_date:yyyyMMdd}");
-            var all_abandon_count = RedisHelper.Get<int>($":total:all:放弃转链:{log_date:yyyyMMdd}");
+            int all_total_count = TkLogCore.GetTotal($":{prefix}total:all:{log_date:yyyyMMdd}");
+            var all_success_count = TkLogCore.GetTotal($":{prefix}total:all:success:{log_date:yyyyMMdd}");
+            var all_abandon_count = TkLogCore.GetTotal($":{prefix}total:all:放弃转链:{log_date:yyyyMMdd}");
 
             string all_success_percentage = string.Empty;
             string all_abandon_percentage = string.Empty;
@@ -104,11 +104,11 @@ namespace molilian.core
                  .Get<dynamic>("log_date=@log_date AND accountId=@accountId", new { log_date, accountId = 0 });
 
             var createArgs2 = new DBContext.Table("daily_logs")
-                .Add("total_count", all_total_count)
-                .Add("abandon_count", all_abandon_count)
-                .Add("abandon_percentage", all_abandon_percentage)
-                .Add("success_count", all_success_count)
-                .Add("success_percentage", all_success_percentage)
+                .Add($"{prefix}total_count", all_total_count)
+                .Add($"{prefix}abandon_count", all_abandon_count)
+                .Add($"{prefix}abandon_percentage", all_abandon_percentage)
+                .Add($"{prefix}success_count", all_success_count)
+                .Add($"{prefix}success_percentage", all_success_percentage)
                 .Add("last_time", DateTime.Now);
 
             if (exist2 == null)

+ 9 - 2
molilian.core/Plus/Alimama/parse.cs

@@ -23,12 +23,19 @@ namespace molilian.core
         private string _api;
         private int _api_id = 0;
         private TkConfigDTO _config;
+        private static string _end_point;
+
+        static AlimamaPlus()
+        {
+            _end_point = Environment.GetEnvironmentVariable("EndPoint");
+        }
+
         public AlimamaPlus(TkPoolDTO account)
         {
             //    string accountName, string tb_token, string floorId, string refpid,
             //    string cookies, string user_agent, string nodeName
             _config = TkConfigCore.Get();
-            
+
 
             _accountId = account.id;
             _accountName = account.name;
@@ -46,7 +53,6 @@ namespace molilian.core
             _api_id = account.api_id;
         }
 
-
         public bool ShouldIgnoreOtherAff(string content)
         {
             TkDataDTO result = new();
@@ -330,6 +336,7 @@ namespace molilian.core
                 shortLinkurl = shortLinkurl,
                 deeplink_url = deeplink_url,
                 create_time = DateTime.Now,
+                end_point = _end_point,
             };
         }
 

+ 174 - 6
molilian.core/Plus/Alimama/parse_2.cs

@@ -141,10 +141,70 @@ namespace molilian.core
             int timeout = _config.rt_max;
             if (deduction == 0) return TimeSpan.FromMilliseconds(timeout);
             timeout = timeout - deduction;
-            if (timeout < 0) return TimeSpan.FromMilliseconds(200);
+            if (timeout <= 200) return TimeSpan.FromMilliseconds(200);
             return TimeSpan.FromMilliseconds(timeout);
         }
 
+        /// <summary>
+        /// 从http获取跳转的url
+        /// </summary>
+        /// <param name="url"></param>
+        /// <returns></returns>
+        async Task<(bool, string)> GetDesiredUrlAsync(string url)
+        {
+            string result;
+            try
+            {
+                Uri uri = new(url);
+
+                if (!uri.Host.Equals("m.tb.cn", StringComparison.OrdinalIgnoreCase)) return (false, "不是淘宝短网址");
+
+                string desiredUrlPattern = "var url = '(.*?)'";
+                WebClientUtility client = new()
+                {
+                    Proxy = _proxy,
+                    UserAgent = Sayaka.Common.ProviderFakeUserAgent.RandomComputer
+                };
+#if DEBUG
+                client.Proxy = null;
+#endif
+                client.Timeout = GetRequestTimeout(0);
+                var response = await client.RequestAsync(url);
+
+                var responseBody = response.Body();
+                result = responseBody;
+                if (response.Successed)
+                {
+
+                    if (response.ResponseMessage.IsSuccessStatusCode)
+                    {
+                        Match match = Regex.Match(responseBody, desiredUrlPattern);
+                        if (match.Success)
+                        {
+                            result = match.Groups[1].Value; // 返回匹配的 URL
+
+                            if (string.IsNullOrEmpty(result)) return (false, "没有匹配的URL");
+                            return (true, result);
+                        }
+                    }
+                    else
+                    {
+                        result = $"{response.ResponseMessage.StatusCode}\n{responseBody}";
+                    }
+                }
+                else
+                {
+                    throw response.ResponseException;
+
+                }
+            }
+            catch (Exception ex)
+            {
+                result = $"{ex.Message}\n{ex.StackTrace}";
+            }
+            return (false, result);
+        }
+
         /// <summary>
         /// 从http获取跳转的url
         /// </summary>
@@ -171,6 +231,7 @@ namespace molilian.core
                 client.Timeout = GetRequestTimeout(0);
                 var response = client.Request(url);
 
+
                 var responseBody = response.Body();
                 result = responseBody;
                 if (response.Successed)
@@ -306,6 +367,106 @@ namespace molilian.core
             result.link_type = LinkTypeEnum.other_aff;
             result.shortLinkurl = null;
         }
+        private async Task<TkDataDTO> InternalTextProcessingAsync(string content, TkDataDTO result)
+        {
+            //(result.success, result.content, result.link_type, result.shortLinkurl) = InternalTextProcessing(content,ref result);
+
+
+            bool success;
+            string resultText;
+            LinkTypeEnum link_type = LinkTypeEnum.unknown;
+
+            string url = GetLink(content);
+            if (!string.IsNullOrEmpty(url))
+            {
+                //排除已知的淘客链接
+                if (IsAffLink(url))
+                {
+                    result.success = false;
+                    result.content = "排除淘客链接";
+                    result.link_type = LinkTypeEnum.other_aff;
+                    result.shortLinkurl = url;
+                    return result;
+                    //return (false, "排除淘客链接", LinkTypeEnum.other_aff, url);
+                }
+
+                //直接提取
+                (success, resultText) = IsTaobaoUrl(url);
+                if (success)
+                {
+                    result.success = true;
+                    result.content = resultText;
+                    result.link_type = LinkTypeEnum.goods;
+                    result.shortLinkurl = resultText;
+                    return result;
+                    //return (true, result, LinkTypeEnum.goods, result);
+                }
+
+                //从http获取跳转的url
+                Stopwatch stopwatch = Stopwatch.StartNew();
+                stopwatch.Start();
+                (success, resultText) = await GetDesiredUrlAsync(url);
+                stopwatch.Stop();
+                // 获取执行时间
+                result.elapsedTime2 = (int)stopwatch.ElapsedMilliseconds;
+
+                if (success)
+                {
+                    //排除已知的淘客链接
+                    if (IsAffLink(resultText))
+                    {
+                        result.success = false;
+                        result.content = "排除淘客链接";
+                        result.link_type = LinkTypeEnum.other_aff;
+                        result.shortLinkurl = url;
+                        return result;
+                        //return (false, "排除淘客链接", LinkTypeEnum.other_aff, url);
+                    }
+                    (success, resultText) = IsTaobaoUrl(resultText);
+                    if (success)
+                    {
+                        result.success = true;
+                        result.content = resultText;
+                        result.link_type = LinkTypeEnum.goods;
+                        result.shortLinkurl = resultText;
+                        return result;
+                        //return (true, resultText, LinkTypeEnum.goods, resultText);
+                    }
+                    link_type = GetLinkType(resultText);
+                }
+                else
+                {
+                    link_type = GetLinkType(url);
+
+                }
+
+                result.success = false;
+                result.content = resultText;
+                result.link_type = link_type;
+                result.shortLinkurl = url;
+                return result;
+
+                //return (false, result, link_type, url);
+            }
+
+            //判断淘客的¥羊角符号
+            if (ContainsSpecialFormat(content))
+            {
+                result.success = false;
+                result.content = "排除淘口令";
+                result.link_type = LinkTypeEnum.other_aff;
+                result.shortLinkurl = null;
+                return result;
+                //return (false, "排除淘口令", LinkTypeEnum.other_aff, null);
+            }
+
+            //todo 临时应急  0614
+            //return (false, "纯口令 没链接", link_type, null);
+            result.success = false;
+            result.content = "纯口令 没链接";
+            result.link_type = LinkTypeEnum.other_aff;
+            result.shortLinkurl = null;
+        }
         private (bool, string, LinkTypeEnum, string) InternalTextProcessing222(string content)
         {
             bool success;
@@ -366,7 +527,7 @@ namespace molilian.core
             return LinkTypeEnum.unknown;
         }
 
-        private void alimamaParse(string content, ref TkDataDTO result)
+        private async Task<TkDataDTO> alimamaParseAsync(string content, TkDataDTO result)
         {
             string t = $"{DateTime.Now.Convert2UnixTimestamp(true)}";
 
@@ -400,7 +561,8 @@ namespace molilian.core
 #endif
             if (!string.IsNullOrEmpty(_user_agent)) client.UserAgent = _user_agent;
             client.Timeout = GetRequestTimeout(result.elapsedTime2);
-            var response = client.Request(url);
+            //var response = client.Request(url);
+            var response = await client.RequestAsync(url);
 
             var body = string.Empty;
             try
@@ -422,7 +584,7 @@ namespace molilian.core
                         throw response.ResponseException;
                     }
 
-                    return;
+                    return result;
                 }
 
 
@@ -540,11 +702,11 @@ namespace molilian.core
                 }
                 throw;
             }
+            return result;
         }
 
 
-
-        private async Task<TkDataDTO> alimamaParseAsync(string content, TkDataDTO result)
+        private TkDataDTO alimamaParse(string content, TkDataDTO result)
         {
             string t = $"{DateTime.Now.Convert2UnixTimestamp(true)}";
 
@@ -578,8 +740,13 @@ namespace molilian.core
             if (!string.IsNullOrEmpty(_user_agent)) client.UserAgent = _user_agent;
 #if DEBUG
             client.Proxy = null;
+
+            url = "https://47.246.177.226/openapi/param2/1/gateway.unionpub/xt.entry.json?" +
+               $"t={t}&_tb_token_={_tb_token}&floorId={_floorId}&refpid={_refpid}&variableMap={variableMap}";
+            client.Headers["Host"] = "pub.alimama.com";
 #endif
             client.Timeout = GetRequestTimeout(result.elapsedTime2);
+            //var response = client.Request(url);
             var response = client.Request(url);
 
             stopwatch.Stop();
@@ -758,5 +925,6 @@ namespace molilian.core
             return result;
         }
 
+         
     }
 }

+ 7 - 0
molilian.core/Plus/DyUnion/DyUnionPlus.cs

@@ -28,6 +28,12 @@ namespace molilian.core
 {
     public partial class DyUnionPlus
     {
+        private static string _end_point;
+        static DyUnionPlus()
+        {
+            _end_point = Environment.GetEnvironmentVariable("EndPoint");
+        }
+
 
         public static DyDataDTO GetFormattedObject(string content, string ip = "", string oaid = "")
         {
@@ -49,6 +55,7 @@ namespace molilian.core
                 deeplink_url = deeplink_url,
                 itemName = "点击打开抖音APP",
                 create_time = DateTime.Now,
+                end_point = _end_point
             };
         }
 

+ 7 - 0
molilian.core/Plus/JDUnion/JdUnionPlus.cs

@@ -23,6 +23,12 @@ namespace molilian.core
 {
     public partial class JdUnionPlus
     {
+        private static string _end_point;
+        static JdUnionPlus()
+        {
+            _end_point = Environment.GetEnvironmentVariable("EndPoint");
+        }
+
         public static string GetLink(string content)
         {
             if (string.IsNullOrEmpty(content)) return content;
@@ -84,6 +90,7 @@ namespace molilian.core
                 shortLinkurl = shortLinkurl,
                 deeplink_url = deeplink_url,
                 create_time = DateTime.Now,
+                end_point = _end_point,
             };
         }
 

+ 33 - 0
molilian.core/Plus/RedisClientManager.cs

@@ -0,0 +1,33 @@
+using CSRedis;
+using dodohold.core;
+
+
+namespace molilian.core
+{
+    public class RedisClientManager
+    {
+        private static Dictionary<string, CSRedisClient> redisClients = [];
+
+        public static CSRedisClient GetRedisClient(string connectionString)
+        {
+            if (!redisClients.ContainsKey(connectionString))
+            {
+                var redisClient = new CSRedisClient(connectionString);
+                redisClients[connectionString] = redisClient;
+            }
+
+            return redisClients[connectionString];
+        }
+
+
+        // 可选:释放 Redis 客户端资源
+        public static void DisposeRedisClients()
+        {
+            foreach (var client in redisClients.Values)
+            {
+                client.Dispose();
+            }
+            redisClients.Clear();
+        }
+    }
+}

+ 7 - 0
molilian.core/Plus/Tool/ToolParsePlus.cs

@@ -24,6 +24,12 @@ namespace molilian.core
 {
     public partial class ToolParsePlus
     {
+        private static string _end_point;
+        static ToolParsePlus()
+        {
+            _end_point = Environment.GetEnvironmentVariable("EndPoint");
+        }
+
         public static string GetLink(string content)
         {
             if (string.IsNullOrEmpty(content)) return content;
@@ -64,6 +70,7 @@ namespace molilian.core
                 elapsedTime = 0,
                 create_time = DateTime.Now,
                 itemName = itemName,
+                end_point = _end_point,
             };
         }
 

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff