Ver Fonte

dy推广联盟下线;
jd转链失败dp带上链接;
unsafeParse接口增加指定账号参数aid ;
后台调用数据增加输出 产商转链和优惠券API的调用数据并只从redis取当天统计(其他统计从mysql获取);

dodo hold há 2 anos atrás
pai
commit
2533697529

+ 34 - 25
molilian.api/Controllers/admin/TaobaoController.cs

@@ -196,37 +196,44 @@ namespace molilian.api.Controllers
 
             foreach (var item in result.List)
             {
-                if (item.total_count > 0) continue;
-                item.total_count = TkLogCore.GetTotal($":total:all:{item.report_date:yyyyMMdd}");
-                if (item.total_count == 0) continue;
-                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)
+                if (item.report_date.Date < DateTime.Now.Date) continue;
+                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}%";
+                    item.total_count = TkLogCore.GetTotal($":total:tb:{item.report_date:yyyyMMdd}");
+                    if (item.total_count == 0) continue;
+                    item.success_count = TkLogCore.GetTotal($":total:tb:success:{item.report_date:yyyyMMdd}");
+                    item.abandon_count = TkLogCore.GetTotal($":total:tb:放弃转链:{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)
+                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}%";
+                    item.parse_total_count = TkLogCore.GetTotal($":parse_total:tb:{item.report_date:yyyyMMdd}");
+                    if (item.parse_total_count == 0) continue;
+                    item.parse_success_count = TkLogCore.GetTotal($":parse_total:tb:success:{item.report_date:yyyyMMdd}");
+                    item.parse_abandon_count = TkLogCore.GetTotal($":parse_total:tb:放弃转链:{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)
+                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}%";
+                    item.coupon_total_count = TkLogCore.GetTotal($":coupon_total:tb:{item.report_date:yyyyMMdd}");
+                    if (item.coupon_total_count == 0) continue;
+                    item.coupon_success_count = TkLogCore.GetTotal($":coupon_total:tb:success:{item.report_date:yyyyMMdd}");
+                    item.coupon_abandon_count = TkLogCore.GetTotal($":coupon_total:tb:放弃转链:{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 });
@@ -288,6 +295,7 @@ namespace molilian.api.Controllers
 
             foreach (var item in result.List)
             {
+                if (item.report_date.Date < DateTime.Now.Date) continue;
                 //var tk = TkPoolCore.GetOne(item.accountId);
                 //if (tk != null) item.accountName = tk.company;
                 string accountName = $"{TkChannelEnum.tb}_{item.accountId}";
@@ -394,6 +402,7 @@ namespace molilian.api.Controllers
 
             foreach (var item in result.List)
             {
+                if (item.report_date.Date < DateTime.Now.Date) continue;
                 string accountName = $"{TkChannelEnum.tb}_{item.accountId}";
                 if (item.total_count == 0)
                 {
@@ -432,7 +441,7 @@ namespace molilian.api.Controllers
                 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}");

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

@@ -79,11 +79,12 @@ namespace molilian.api.Controllers
             var channel = form.Read("c", string.Empty);
             var ip = form.Read("ip", string.Empty);
             var oaid = form.Read("oaid", string.Empty);
+            int accountid = form.Read("aid", 0);
 #if DEBUG
             ip = "127.0.0.1";
             oaid = "test-oaid";
 #endif
-            return await UnionParseCore.UnionParseAsync(content, channel, ip, oaid);
+            return await UnionParseCore.UnionParseAsync(content, channel, ip, oaid, accountid);
         }
 
         //[HttpGet]

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


+ 1 - 1
molilian.api/molilian.api.csproj

@@ -9,7 +9,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="dodohold.core" Version="1.0.1.11" />
+    <PackageReference Include="dodohold.core" Version="1.0.1.12" />
     <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.0-Preview.1" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
   </ItemGroup>

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

@@ -79,7 +79,7 @@ namespace molilian.core
             await Task.WhenAll(tasks);
         }
 
-        public static async Task NotifyReload(bool onlyAccount = false)
+        public static async Task NotifyReload(bool onlyAccount = false, CancellationToken cancellationToken = default)
         {
             await ProcessEndPointNodesAsync(async node =>
             {
@@ -87,7 +87,7 @@ namespace molilian.core
                 {
                     string url = $"{node.api_server}Task_70160bd632/reload";
                     if (onlyAccount) url = $"{node.api_server}Task_70160bd632/reloadAccount";
-                    await new WebClientUtility().RequestAsync(url);
+                    await new WebClientUtility().RequestAsync(url, "GET", cancellationToken);
                 }
                 catch (Exception ex)
                 {

+ 21 - 8
molilian.core/Core/taoke/TkLogCore.cs

@@ -684,20 +684,33 @@ namespace molilian.core
 
         public static int GetTotal(string keyname, bool all_node = true)
         {
-            int result = RedisHelper.Get<int>(keyname);
-            return result;
+            var result = EndPointCore.ProcessEndPointNodes<int>(node =>
+            {
+                if (!node.is_public_api) return 0;
+                var redis = RedisClientManager.GetRedisClient(node.redis_server);
+                return redis.Get<int>(keyname);
+            });
+            return result.Sum();
         }
 
         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();
+            var result = EndPointCore.ProcessEndPointNodes<string[]>(node =>
+            {
+                if (!node.is_public_api) return [];
+                var redis = RedisClientManager.GetRedisClient(node.redis_server);
+
+                string[] message_keys = redis.SMembers(keyname);
+                return message_keys;
+            });
 
-            //string[] message_keys3 = RedisHelper.SMembers(keyname.Replace(":total:", ":coupon_total:"));
-            //message_keys = message_keys.Union(message_keys3).ToArray();
+            string[] message_keys = [];
+            foreach (var arr in result)
+            {
+                message_keys = message_keys.Union(arr).ToArray();
+            }
+            return message_keys;
         }
 
 

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

@@ -16,6 +16,7 @@ using Spire.Pdf.Graphics;
 using Google.Protobuf.WellKnownTypes;
 using System.Threading.Channels;
 using TencentCloud.Weilingwith.V20230427.Models;
+using System.Threading;
 
 
 namespace molilian.core

+ 268 - 9
molilian.core/Core/taoke/UnionParseCore.cs

@@ -14,6 +14,10 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Authentication;
 using Spire.Pdf.Graphics;
 using Google.Protobuf.WellKnownTypes;
+using TencentCloud.Tcm.V20210413.Models;
+using System.Diagnostics;
+using System.Threading;
+using TencentCloud.Soe.V20180724.Models;
 
 
 namespace molilian.core
@@ -21,7 +25,7 @@ namespace molilian.core
     public partial class UnionParseCore
     {
 
-        public static async Task<ActionResult> UnionParseAsync(string content, string channel, string ip, string oaid)
+        public static async Task<ActionResult> UnionParseAsync(string content, string channel, string ip, string oaid, int accountid = 0)
         {
             return channel switch
             {
@@ -29,7 +33,7 @@ namespace molilian.core
                 "bdpan" => PanParse(content, ip, oaid),
                 "jd" => await JdParseAsync(content, ip, oaid),
                 "dy" => await DyParseAsync(content, ip, oaid),
-                _ => await TaobaoParseAsync(content, ip, oaid),
+                _ => await TaobaoParseAsync(content, ip, oaid, accountid),
             };
         }
 
@@ -110,16 +114,244 @@ namespace molilian.core
             }, result.success ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
         }
 
-        public static async Task<APIResult> TaobaoParseAsync(string content, string ip = "", string oaid = "")
+
+        private static APIResult TaobaoParseOutput(TkDataDTO result, Dictionary<string, long> swData, object info, APIResultCodeEnum code = APIResultCodeEnum.OK)
+        {
+            if (result.elapsedTime > 2000)
+            {
+                LoggerLibrary log = new("debug", "stopwatch");
+                foreach ((var key, var value) in swData)
+                {
+                    log.Info($"{key}\t{value}");
+                }
+                log.SaveAsync();
+            }
+            return new APIResult(info, code);
+        }
+
+        public static async Task<APIResult> TaobaoParseAsync(string content,
+            string ip = "", string oaid = "",
+            int accountid = 0)
+        {
+            AlimamaPlus alimama = null;
+            content = content.UrlDecode();
+            content = content[..Math.Min(1000, content.Length)];
+            var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);
+
+            Dictionary<string, long> swData = new();
+            swData.Add("StartNew", 0);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+
+            result.rawContent = content;
+            try
+            {
+                bool is_other = AlimamaPlus.OtherPlatform(content);
+                stopwatch.Stop();
+                swData.Add("OtherPlatform", stopwatch.ElapsedMilliseconds);
+
+                if (is_other)
+                {
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.reason = "平台错误";
+
+                    _ = TkLogCore.ParseLogAsync(result);
+                    return TaobaoParseOutput(result, swData, new
+                    {
+                        channel = result?.channel.ToString(),
+                        result.success,
+                        result.message,
+                        result.shortLinkurl,
+                        result.deeplink_url,
+                    }, APIResultCodeEnum.NotAcceptable);
+                }
+
+                stopwatch.Reset();
+                stopwatch.Start();
+                string reason = string.Empty;
+                bool is_ignore = AlimamaPlus.FirstFilterIgnoreRequest(content, out reason);
+                stopwatch.Stop();
+                swData.Add("FirstFilterIgnoreRequest", stopwatch.ElapsedMilliseconds);
+
+                if (string.IsNullOrEmpty(result.shortLinkurl) && is_ignore)
+                {
+                    //没有短链接都放弃
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.itemName = "点击打开淘宝APP";
+                    result.reason = "初步筛选";
+                    _ = TkLogCore.ParseLogAsync(result);
+                    return TaobaoParseOutput(result, swData, new
+                    {
+                        result.success,
+                        result.message,
+                        result.content,
+                        result.itemName,
+                        result.deeplink_url,
+                    });
+                }
+
+
+                stopwatch.Reset();
+                stopwatch.Start();
+                bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out reason);
+                stopwatch.Stop();
+                swData.Add("ShouldIgnoreRequest", stopwatch.ElapsedMilliseconds);
+
+                if (is_ignore2)
+                {
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.itemName = "点击打开淘宝APP";
+                    result.reason = reason;
+                    _ = TkLogCore.ParseLogAsync(result);
+                    return TaobaoParseOutput(result, swData, new
+                    {
+                        result.success,
+                        result.message,
+                        result.content,
+                        result.itemName,
+                        result.deeplink_url,
+                    });
+                }
+
+                stopwatch.Reset();
+                stopwatch.Start();
+                TkPoolDTO? account = accountid > 0 ?
+                    TkPoolCore.GetOne(accountid) :
+                    TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
+
+                stopwatch.Stop();
+                swData.Add("GetOne", stopwatch.ElapsedMilliseconds);
+
+                if (account == null)
+                {
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.reason = "没有匹配账号";
+                    result.itemName = "点击打开淘宝APP";
+                    _ = TkLogCore.ParseLogAsync(result);
+                    return TaobaoParseOutput(result, swData, new
+                    {
+                        result.success,
+                        result.message,
+                        result.content,
+                        result.couponAmount,
+                        result.taoToken,
+                        result.shortLinkurl,
+                        result.deeplink_url,
+                    });
+                }
+                result.accountId = account.id;
+
+                stopwatch.Reset();
+                stopwatch.Start();
+                alimama = new AlimamaPlus(account);
+                stopwatch.Stop();
+                swData.Add("AlimamaPlus", stopwatch.ElapsedMilliseconds);
+
+                int timeout = alimama._config.rt_max - result.elapsedTime2;
+                using var cts = new CancellationTokenSource();
+                cts.CancelAfter(timeout);
+
+                stopwatch.Reset();
+                stopwatch.Start();
+
+
+
+                var requestTask = alimama.UnionParse2Async(content, result, cts.Token, swData);
+                var delayTask = Task.Delay(timeout, cts.Token);
+                var completedTask = await Task.WhenAny(requestTask, delayTask);
+                if (completedTask == requestTask)
+                {
+                    result = await requestTask;
+                }
+                else
+                {
+                    cts.Cancel();
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.reason = "请求超时";
+                    result.itemName = "点击打开淘宝APP";
+                }
+
+                stopwatch.Stop();
+                swData.Add("UnionParse2Async", stopwatch.ElapsedMilliseconds);
+
+                //result = await alimama.UnionParse2Async(content, result);
+                result.accountName = account.company;
+            }
+            catch (Exception ex)
+            {
+                if (ex.Message.Contains("was canceled"))
+                {
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.reason = "请求超时";
+                    result.itemName = "点击打开淘宝APP";
+                }
+                else
+                {
+                    _ = new LoggerLibrary("unionParse", "tb_error")
+                        .Info(ip, oaid)
+                        .Info(content)
+                        .Info(ex.Message, ex.StackTrace)
+                        .SaveAsync();
+
+                    NotifyCore.Notify(new NifyMessage
+                    {
+                        message = $"【转链异常TB】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
+                        priority = NifyMessagePriority.high,
+                        tags = ["red_circle"]
+                    });
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.reason = "转链接口异常";
+                    result.itemName = "点击打开淘宝APP";
+                }
+            }
+            _ = TkLogCore.ParseLogAsync(result, alimama);
+
+            return TaobaoParseOutput(result, swData, new
+            {
+                result.success,
+                result.message,
+                link_type = result.link_type.ToString(),
+                channel = result?.channel.ToString(),
+                result.channel_type,
+                result.itemId,
+                result.itemName,
+                result.pic,
+                result.promotionPrice,
+                result.couponAmount,
+                result.couponEffectiveStartTime,
+                result?.couponEffectiveEndTime,
+                result.shortLinkurl,
+                result.deeplink_url,
+                result.content,
+                result.taoToken,
+            });
+        }
+
+        public static async Task<APIResult> TaobaoParseAsync222(string content, string ip = "", string oaid = "")
         {
             AlimamaPlus alimama = null;
             content = content.UrlDecode();
             content = content[..Math.Min(1000, content.Length)];
             var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);
+
+            LoggerLibrary log = new("debug", "stopwatch");
+            log.Info($"StartNew", content);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+
             result.rawContent = content;
             try
             {
-                if (AlimamaPlus.OtherPlatform(content))
+                bool is_other = AlimamaPlus.OtherPlatform(content);
+                stopwatch.Stop();
+                log.Info($"AlimamaPlus.OtherPlatform\t{stopwatch.ElapsedMilliseconds}");
+
+                if (is_other)
                 {
                     result.success = false;
                     result.message = "放弃转链";
@@ -191,7 +423,26 @@ namespace molilian.core
                 }
                 result.accountId = account.id;
                 alimama = new AlimamaPlus(account);
-                result = await alimama.UnionParse2Async(content, result);
+                int timeout = alimama._config.rt_max;
+
+                using var cts = new CancellationTokenSource();
+                cts.CancelAfter(timeout);
+                var requestTask = alimama.UnionParse2Async(content, result, cts.Token);
+                var delayTask = Task.Delay(timeout, cts.Token);
+                var completedTask = await Task.WhenAny(requestTask, delayTask);
+                if (completedTask == requestTask)
+                {
+                    result = await requestTask;
+                }
+                else
+                {
+                    cts.Cancel();
+                    result.success = false;
+                    result.message = "放弃转链";
+                    result.reason = "请求超时";
+                    result.itemName = "点击打开淘宝APP";
+                }
+                //result = await alimama.UnionParse2Async(content, result);
                 result.accountName = account.company;
             }
             catch (Exception ex)
@@ -290,7 +541,7 @@ namespace molilian.core
         //    }
         //}
 
-        public static async Task<APIResult> JdParseAsync(string content, string ip, string oaid)
+        public static async Task<APIResult> JdParseAsync(string content, string ip, string oaid, CancellationToken cancellationToken = default)
         {
             var result = JdUnionPlus.GetFormattedObject(content, ip, oaid);
             content = content.UrlDecode();
@@ -316,7 +567,7 @@ namespace molilian.core
                     _ = TkLogCore.ParseLogAsync(result);
                     return new APIResult(result);
                 }
-                result = await JdUnionPlus.JdParseAsync(account, content, result);
+                result = await JdUnionPlus.JdParseAsync(account, content, result, cancellationToken);
             }
             catch (Exception ex)
             {
@@ -360,7 +611,7 @@ namespace molilian.core
             }, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
         }
 
-        public static async Task<APIResult> DyParseAsync(string content, string ip, string oaid)
+        public static async Task<APIResult> DyParseAsync(string content, string ip, string oaid, CancellationToken cancellationToken = default)
         {
             var result = DyUnionPlus.GetFormattedObject(content, ip, oaid);
             content = content.UrlDecode();
@@ -368,6 +619,14 @@ namespace molilian.core
             bool IfExceptional = false;
             try
             {
+                // 2024-06-19 联盟业务下线
+                result.success = false;
+                result.message = "放弃转链";
+                result.reason = "联盟下线";
+                _ = TkLogCore.ParseLogAsync(result);
+                return new APIResult(result);
+
+
                 if (DyUnionPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
                 {
                     result.success = false;
@@ -386,7 +645,7 @@ namespace molilian.core
                     _ = TkLogCore.ParseLogAsync(result);
                     return new APIResult(result);
                 }
-                result = await DyUnionPlus.DyParseAsync(account, content, result);
+                result = await DyUnionPlus.DyParseAsync(account, content, result, cancellationToken);
             }
             catch (Exception ex)
             {

+ 2 - 2
molilian.core/Plus/Alimama/coupon.cs

@@ -9,10 +9,10 @@ namespace molilian.core
 {
     public partial class AlimamaPlus
     {
-        internal async Task<UnionCouponDTO> UnionCoupon2Async(string content, UnionCouponDTO result)
+        internal async Task<UnionCouponDTO> UnionCoupon2Async(string content, UnionCouponDTO result, CancellationToken cancellationToken = default)
         {
             TkDataDTO data = new();
-            data = await alimamaParseAsync(content, data);
+            data = await alimamaParseAsync(content, data, cancellationToken);
 
             result.channel = data.channel;
             result.success = data.success;

+ 29 - 6
molilian.core/Plus/Alimama/parse.cs

@@ -4,6 +4,7 @@ using System.Text.RegularExpressions;
 using System.Net;
 using System.Security.Cryptography;
 using TencentCloud.Ecm.V20190719.Models;
+using System.Diagnostics;
 
 namespace molilian.core
 {
@@ -22,8 +23,9 @@ namespace molilian.core
 
         private string _api;
         private int _api_id = 0;
-        private TkConfigDTO _config;
+        public TkConfigDTO _config;
         private static string _end_point;
+        static Random _random = new Random();
 
         static AlimamaPlus()
         {
@@ -90,9 +92,18 @@ namespace molilian.core
             return result;
         }
 
-        public async Task<TkDataDTO> UnionParseAsync(string content, TkDataDTO result)
+        public async Task<TkDataDTO> UnionParseAsync(string content, TkDataDTO result,
+            CancellationToken cancellationToken = default,
+            Dictionary<string, long> swData = null)
         {
-            result = await InternalTextProcessingAsync(content, result);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            result = await InternalTextProcessingAsync(content, result, cancellationToken, swData);
+            if (swData != null)
+            {
+                stopwatch.Stop();
+                swData.Add("InternalTextProcessingAsync", stopwatch.ElapsedMilliseconds);
+            }
+
             //(result.success, result.content, result.link_type, result.shortLinkurl) = InternalTextProcessing(content);
             if (result.link_type == LinkTypeEnum.other_aff)
             {
@@ -112,7 +123,20 @@ namespace molilian.core
                 //处理过后的正文 用于转链
                 if (!result.success) { result.content = content; }
 
-                result = await alimamaParseAsync(result.content, result);
+
+                if (swData != null)
+                {
+                    stopwatch.Reset();
+                    stopwatch.Start();
+                }
+                result = await alimamaParseAsync(result.content, result, cancellationToken);
+
+                if (swData != null)
+                {
+                    stopwatch.Stop();
+                    swData.Add("alimamaParseAsync", stopwatch.ElapsedMilliseconds);
+                }
+
                 if (!result.success)
                 {
                     result.itemName = "点击打开淘宝APP";
@@ -301,8 +325,7 @@ namespace molilian.core
 
                 int ignorePercentage = config.ignorePercentage;
                 if (ignorePercentage == 0) return false;
-                Random random = new Random();
-                var randomValue = (decimal)random.Next(0, 100);
+                var randomValue = (decimal)_random.Next(0, 100);
                 bool result = randomValue <= ignorePercentage; // 如果生成的随机数小于忽略百分比,则返回 true,表示需要忽略请求
                 if (result) reason = "流量控制";
                 return result;

+ 102 - 23
molilian.core/Plus/Alimama/parse_2.cs

@@ -25,7 +25,7 @@ namespace molilian.core
             UnionParse(content, ref result);
         }
 
-        public async Task<TkDataDTO> UnionParse2Async(string content, TkDataDTO result)
+        public async Task<TkDataDTO> UnionParse2Async(string content, TkDataDTO result, CancellationToken cancellationToken = default, Dictionary<string, long> swData = null)
         {
             if ("veapi".Equals(_api) && _api_id > 0)
             {
@@ -33,11 +33,11 @@ namespace molilian.core
                 if (account != null)
                 {
                     var core = new VeapiPlus(account.name, account.key, account.sessionKey);
-                    result = await core.UnionParseAsync(content, result);
+                    result = await core.UnionParseAsync(content, result, cancellationToken);
                     return result;
                 }
             }
-            result = await UnionParseAsync(content, result);
+            result = await UnionParseAsync(content, result, cancellationToken, swData);
             return result;
         }
 
@@ -137,12 +137,19 @@ namespace molilian.core
 #if DEBUG
             //return TimeSpan.FromMilliseconds(10 * 1000);
 #endif
+            int min = (int)(_config.rt_max * 0.3);
             if (_config.rt_max == 0) return TimeSpan.FromMilliseconds(1000);
+
             int timeout = _config.rt_max;
-            if (deduction == 0) return TimeSpan.FromMilliseconds(timeout);
+            if (deduction == 0)
+            {
+                timeout -= min;
+                return TimeSpan.FromMilliseconds(timeout);
+            }
+
             timeout = timeout - deduction;
-            if (timeout <= 200) return TimeSpan.FromMilliseconds(200);
-            return TimeSpan.FromMilliseconds(timeout);
+            if (timeout <= min) return TimeSpan.FromMilliseconds(min);
+            return TimeSpan.FromMilliseconds(min);
         }
 
         /// <summary>
@@ -150,7 +157,7 @@ namespace molilian.core
         /// </summary>
         /// <param name="url"></param>
         /// <returns></returns>
-        async Task<(bool, string)> GetDesiredUrlAsync(string url)
+        async Task<(bool, string)> GetDesiredUrlAsync(string url, CancellationToken cancellationToken = default)
         {
             string result;
             try
@@ -169,7 +176,7 @@ namespace molilian.core
                 client.Proxy = null;
 #endif
                 client.Timeout = GetRequestTimeout(0);
-                var response = await client.RequestAsync(url);
+                var response = await client.RequestAsync(url, "GET", cancellationToken);
 
                 var responseBody = response.Body();
                 result = responseBody;
@@ -367,18 +374,42 @@ namespace molilian.core
             result.link_type = LinkTypeEnum.other_aff;
             result.shortLinkurl = null;
         }
-        private async Task<TkDataDTO> InternalTextProcessingAsync(string content, TkDataDTO result)
+        private async Task<TkDataDTO> InternalTextProcessingAsync(string content, TkDataDTO result,
+            CancellationToken cancellationToken,
+            Dictionary<string, long> swData = null)
         {
-            //(result.success, result.content, result.link_type, result.shortLinkurl) = InternalTextProcessing(content,ref result);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+
             bool success;
             string resultText;
             LinkTypeEnum link_type = LinkTypeEnum.unknown;
 
+
+            if (swData != null)
+            {
+                stopwatch.Reset();
+                stopwatch.Start();
+            }
             string url = GetLink(content);
+            if (swData != null)
+            {
+                stopwatch.Stop();
+                swData.Add("\tGetLink", stopwatch.ElapsedMilliseconds);
+            }
             if (!string.IsNullOrEmpty(url))
             {
-                //排除已知的淘客链接
-                if (IsAffLink(url))
+                if (swData != null)
+                {
+                    stopwatch.Reset();
+                    stopwatch.Start();
+                }
+                bool is_aff = IsAffLink(url);
+                if (swData != null)
+                {
+                    stopwatch.Stop();
+                    swData.Add("\t\tGetLink", stopwatch.ElapsedMilliseconds);
+                }
+                if (is_aff)
                 {
                     result.success = false;
                     result.content = "排除淘客链接";
@@ -389,7 +420,18 @@ namespace molilian.core
                 }
 
                 //直接提取
+
+                if (swData != null)
+                {
+                    stopwatch.Reset();
+                    stopwatch.Start();
+                }
                 (success, resultText) = IsTaobaoUrl(url);
+                if (swData != null)
+                {
+                    stopwatch.Stop();
+                    swData.Add("\tIsTaobaoUrl", stopwatch.ElapsedMilliseconds);
+                }
                 if (success)
                 {
                     result.success = true;
@@ -400,18 +442,32 @@ namespace molilian.core
                     //return (true, result, LinkTypeEnum.goods, result);
                 }
 
-                //从http获取跳转的url
-                Stopwatch stopwatch = Stopwatch.StartNew();
-                stopwatch.Start();
-                (success, resultText) = await GetDesiredUrlAsync(url);
-                stopwatch.Stop();
+                Stopwatch sw = Stopwatch.StartNew();
+                (success, resultText) = await GetDesiredUrlAsync(url, cancellationToken);
+                sw.Stop();
                 // 获取执行时间
-                result.elapsedTime2 = (int)stopwatch.ElapsedMilliseconds;
-
+                result.elapsedTime2 = (int)sw.ElapsedMilliseconds;
+                if (swData != null)
+                {
+                    swData.Add("\tGetDesiredUrlAsync", sw.ElapsedMilliseconds);
+                }
                 if (success)
                 {
                     //排除已知的淘客链接
-                    if (IsAffLink(resultText))
+
+                    if (swData != null)
+                    {
+                        stopwatch.Reset();
+                        stopwatch.Start();
+                    }
+                    bool is_aff2 = IsAffLink(resultText);
+                    if (swData != null)
+                    {
+                        stopwatch.Stop();
+                        swData.Add("\t\tIsAffLink", stopwatch.ElapsedMilliseconds);
+                    }
+
+                    if (is_aff2)
                     {
                         result.success = false;
                         result.content = "排除淘客链接";
@@ -420,7 +476,18 @@ namespace molilian.core
                         return result;
                         //return (false, "排除淘客链接", LinkTypeEnum.other_aff, url);
                     }
+
+                    if (swData != null)
+                    {
+                        stopwatch.Reset();
+                        stopwatch.Start();
+                    }
                     (success, resultText) = IsTaobaoUrl(resultText);
+                    if (swData != null)
+                    {
+                        stopwatch.Stop();
+                        swData.Add("\t\tIsTaobaoUrl", stopwatch.ElapsedMilliseconds);
+                    }
                     if (success)
                     {
                         result.success = true;
@@ -447,8 +514,20 @@ namespace molilian.core
                 //return (false, result, link_type, url);
             }
 
+
+            if (swData != null)
+            {
+                stopwatch.Reset();
+                stopwatch.Start();
+            }
+            bool is_aff3 = ContainsSpecialFormat(content);
+            if (swData != null)
+            {
+                stopwatch.Stop();
+                swData.Add("\tContainsSpecialFormat", stopwatch.ElapsedMilliseconds);
+            }
             //判断淘客的¥羊角符号
-            if (ContainsSpecialFormat(content))
+            if (is_aff3)
             {
                 result.success = false;
                 result.content = "排除淘口令";
@@ -526,7 +605,7 @@ namespace molilian.core
             return LinkTypeEnum.unknown;
         }
 
-        private async Task<TkDataDTO> alimamaParseAsync(string content, TkDataDTO result)
+        private async Task<TkDataDTO> alimamaParseAsync(string content, TkDataDTO result, CancellationToken cancellationToken = default)
         {
             string t = $"{DateTime.Now.Convert2UnixTimestamp(true)}";
 
@@ -564,7 +643,7 @@ namespace molilian.core
             if (!string.IsNullOrEmpty(_user_agent)) client.UserAgent = _user_agent;
             client.Timeout = GetRequestTimeout(result.elapsedTime2);
             //var response = client.Request(url);
-            var response = await client.RequestAsync(url);
+            var response = await client.RequestAsync(url, "GET", cancellationToken);
 
             stopwatch.Stop();
             result.elapsedTime3 = (int)stopwatch.ElapsedMilliseconds;

+ 2 - 2
molilian.core/Plus/DyUnion/DyUnionPlus.cs

@@ -225,7 +225,7 @@ namespace molilian.core
             return baseDeeplink;
         }
 
-        public static async Task<DyDataDTO> DyParseAsync(PangolinDTO account, string content, DyDataDTO result)
+        public static async Task<DyDataDTO> DyParseAsync(PangolinDTO account, string content, DyDataDTO result, CancellationToken cancellationToken = default)
         {
             var plus = new DyUnionPlus(account.app_key, account.app_secret);
 
@@ -263,7 +263,7 @@ namespace molilian.core
                 case LinkTypeEnum.live:
 
                     {
-                        result = await plus.Parse(url, result);
+                        result = await plus.ParseAsync(url, result, cancellationToken);
                         return result;
                     }
                 //case LinkTypeEnum.live:

+ 4 - 4
molilian.core/Plus/DyUnion/base.cs

@@ -41,12 +41,12 @@ namespace molilian.core
         }
 
 
-        public async Task<DyDataDTO> Parse(string content, DyDataDTO result)
+        public async Task<DyDataDTO> ParseAsync(string content, DyDataDTO result, CancellationToken cancellationToken = default)
         {
             string path = "/command_parse";
             string post = new { command = content, share_type = new int[] { 1, 3, 5 } }.Convert2Json();
 
-            var body = await RequestAsync(path, post);
+            var body = await RequestAsync(path, post, cancellationToken);
             //{"code":500000,"desc":"command parse error:商品没有加入精选联盟"}
             //{"code":500000,"desc":"command parse error:商家已设置该商品仅指定作者可推广,请您更换其他商品"}
             //{"code":0,"desc":"","data":{"command_type":1,"product_info":{"product_id":3660263780149019445,"share_info":{"deeplink":"snssdk1128://lynxview?surl=https%3A%2F%2Flf-dy-sourcecdn-tos.bytegecko.com%2Fobj%2Fbyte-gurd-source%2F1325%2Fgecko%2Fresource%2Ffe_lynx_distribution_landing%2Fapp%2Ftemplate.js&hide_nav_bar=1&hide_status_bar=1&token=ijRcTEAk&distribution_ab=1&alliance_distribution=1","share_command":"","zlink":"","share_link":""}}}}
@@ -135,7 +135,7 @@ namespace molilian.core
         //}
 
 
-        public async Task<string> RequestAsync(string path, string data)
+        public async Task<string> RequestAsync(string path, string data, CancellationToken cancellationToken = default)
         {
             int timestamp = DateTime.Now.Convert2UnixTimestamp();
             string req_id = Guid.NewGuid().ToString();
@@ -156,7 +156,7 @@ namespace molilian.core
             var client = new WebClientUtility();
             client.SetContentType("application/json");
             client.Post(postData);
-            var response = await client.RequestAsync(url);
+            var response = await client.RequestAsync(url, "POST", cancellationToken);
             var body = response.Body();
             _ = log.Info(body).SaveAsync();
 

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

@@ -207,10 +207,11 @@ namespace molilian.core
         //    return result;
         //}
 
-        public static async Task<JdDataDTO> JdParseAsync(JdPoolDTO account, string content, JdDataDTO result)
+        public static async Task<JdDataDTO> JdParseAsync(JdPoolDTO account, string content, JdDataDTO result, CancellationToken cancellationToken = default)
         {
             string message = "OK";
             string url = GetLink(content);
+            string shortLinkurl = url;
             var plus = new JdUnionPlus(account.app_key, account.app_secret);
 
             //result.link_type = plus.IsAffLlink(url) ? LinkTypeEnum.other_aff : LinkTypeEnum.goods;
@@ -230,15 +231,19 @@ namespace molilian.core
                 result.deeplink_url = GetDeeplink(url);
                 return result;
             }
-            string shortLinkurl = await plus.GetPromotionAsync(account.site_id, url);
-            var success = !string.IsNullOrEmpty(shortLinkurl);
-            if (!success) message = "转链失败";
+            result.shortLinkurl = await plus.GetPromotionAsync(account.site_id, url, cancellationToken);
+            var success = !string.IsNullOrEmpty(result.shortLinkurl);
+            if (!success)
+            {
+                result.shortLinkurl = shortLinkurl;
+                message = "转链失败";
+            }
 
-            result.content = shortLinkurl;
-            result.shortLinkurl = shortLinkurl;
+            result.content = result.shortLinkurl;
+            result.shortLinkurl = result.shortLinkurl;
             result.success = success;
             result.message = message;
-            result.deeplink_url = GetDeeplink(shortLinkurl);
+            result.deeplink_url = GetDeeplink(result.shortLinkurl);
             return result;
         }
     }

+ 2 - 2
molilian.core/Plus/JDUnion/base.cs

@@ -83,7 +83,7 @@ namespace molilian.core
             //var root = body.Convert2JsonElement();
             return body;
         }
-        public async Task<string> RequestAsync(string method, string version, string param_json)
+        public async Task<string> RequestAsync(string method, string version, string param_json, CancellationToken cancellationToken = default)
         {
             var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
             var sign = _sign(method, version, param_json, timestamp);
@@ -102,7 +102,7 @@ namespace molilian.core
 
             var log = new LoggerLibrary("jdunion", method).Info(url);
             var client = new WebClientUtility();
-            var response = await client.RequestAsync(url);
+            var response = await client.RequestAsync(url, "GET", cancellationToken);
             var body = response.Body();
             _ = log.Info(body).SaveAsync();
 

+ 1 - 1
molilian.core/Plus/JDUnion/coupon.cs

@@ -23,7 +23,7 @@ namespace molilian.core
 {
     public partial class JdUnionPlus
     {
-        internal static async Task<UnionCouponDTO> JdCouponAsync(JdPoolDTO account, DataokeDTO api, string content, UnionCouponDTO result)
+        internal static async Task<UnionCouponDTO> JdCouponAsync(JdPoolDTO account, DataokeDTO api, string content, UnionCouponDTO result, CancellationToken cancellationToken = default)
         {
 
             //result.channel = data.channel;

+ 2 - 2
molilian.core/Plus/JDUnion/goods.cs

@@ -65,7 +65,7 @@ namespace molilian.core
         }
 
 
-        public async Task<string> GetPromotionAsync(string siteId, string materialId)
+        public async Task<string> GetPromotionAsync(string siteId, string materialId, CancellationToken cancellationToken = default)
         {
 
             string method = "jd.union.open.promotion.common.get";
@@ -80,7 +80,7 @@ namespace molilian.core
                     chainType = 2,
                 }
             };
-            var body = await RequestAsync(method, version, data.Convert2Json());
+            var body = await RequestAsync(method, version, data.Convert2Json(), cancellationToken);
             var root = body.Convert2Object<JdUnionResponse>();
             string code = root.jd_union_open_promotion_common_get_responce.code;
             if ("0".Equals(code))

+ 2 - 2
molilian.core/Plus/Tool/ToolParsePlus.cs

@@ -114,7 +114,7 @@ namespace molilian.core
         }
 
 
-        public static void PanParse(string content, ref ToolParseDataDTO result)
+        public static void PanParse(string content, ref ToolParseDataDTO result, CancellationToken cancellationToken = default)
         {
             string message = "OK";
             string surl = string.Empty, pwd = string.Empty;
@@ -139,7 +139,7 @@ namespace molilian.core
             result.deeplink_url = deeplink_url;
         }
 
-        public static void WemeetParse(string content, ref ToolParseDataDTO result)
+        public static void WemeetParse(string content, ref ToolParseDataDTO result, CancellationToken cancellationToken = default)
         {
             string message = "OK";
             string wemeetId = GetWemeetId(content);

+ 2 - 2
molilian.core/Plus/VeapiPlus.cs

@@ -61,12 +61,12 @@ namespace molilian.core
         }
 
 
-        public async Task<TkDataDTO> UnionParseAsync(string content, TkDataDTO result)
+        public async Task<TkDataDTO> UnionParseAsync(string content, TkDataDTO result, CancellationToken cancellationToken)
         {
             string para = content.UrlEncode();
             string url = $"http://api.veapi.cn/tbk/hcapi?vekey={_key}&sessionkey={_sessionKey}&para={para}";
 
-            var response = await new WebClientUtility().RequestAsync(url);
+            var response = await new WebClientUtility().RequestAsync(url, "GET", cancellationToken);
 
             var body = response.Body();
             var root = body.Convert2JsonElement();

+ 1 - 1
molilian.core/molilian.core.csproj

@@ -13,7 +13,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="dodohold.core" Version="1.0.1.11" />
+    <PackageReference Include="dodohold.core" Version="1.0.1.12" />
     <PackageReference Include="FakeUserAgent" Version="1.0.2" />
     <PackageReference Include="IP2Region.Net" Version="2.0.2" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />

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