Ver código fonte

重构 OverrideRuleCore

dodo hold 10 meses atrás
pai
commit
15594670e6

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
molilian.api/Properties/PublishProfiles/latest.pubxml.user


+ 69 - 7
molilian.core/Core/OverrideRuleCore.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Data;
 using System.Security.Cryptography;
 using System.Text.RegularExpressions;
+using System.Web;
 using YunhuiKit;
 
 
@@ -102,32 +103,35 @@ namespace molilian.core
 
             foreach (var item in list)
             {
+                //
                 if (!request.Channel.Equals(item.platform)) continue;
-                if (string.IsNullOrEmpty(item.original_text)) continue;
                 if (item.use_special_text == 1 && request.SpecialText != 1) continue;
 
+                string original_text = item.original_text;
+                if (item.use_special_text == 1) original_text = request.QueryText;
+                if (string.IsNullOrEmpty(original_text)) continue;
+
                 switch (item.rule)
                 {
                     case "regex":
-                        Match match = Regex.Match(content, item.original_text);
+                        Match match = Regex.Match(content, original_text);
                         if (!match.Success) continue;
                         break;
                     case "text":
-                        if (!content.Equals(item.original_text)) continue;
+                        if (!content.Equals(original_text)) continue;
                         break;
                     default:
-                        if (!content.Contains(item.original_text)) continue;
+                        if (!content.Contains(original_text)) continue;
                         break;
                 }
+                if (item.use_special_text == 1 && request.SpecialText != 1) continue;
+
                 if (item.use_risk_control)
                 {
                     bool is_ignore = AlimamaPlus.ShouldIgnoreRequest(request.Ip, request.Oaid, request.RiskStrategy, request.LaunchScene, out _);
                     if (is_ignore) continue;
                 }
 
-                if (item.use_special_text == 1 && request.SpecialText != 1) continue;
-
-
                 // 每小时调用次数统计(无论是否设置限制都要记录)
                 string hourlyKey = $":override_rule_calls:{item.id}:{DateTime.Now:yyyyMMddHH}";
                 try
@@ -165,11 +169,69 @@ namespace molilian.core
                     // Redis错误时记录日志但不阻塞业务
                     _ = new LoggerLibrary("OverrideRule", "Redis").Info($"Daily limit check failed: {ex.Message}", ex.StackTrace).SaveAsync();
                 }
+
+                // 关键词统计 - 长期缓存(6个月)用于历史数据分析
+                await SaveKeywordStatisticsAsync(item.id, item.platform, original_text);
+
+                string output_text = item.output_text;
+                if (output_text.Contains("{url:query_text}")) output_text = output_text.Replace("{url:query_text}", HttpUtility.UrlEncode(original_text));
+                if (output_text.Contains("{url2:query_text}")) output_text = output_text.Replace("{url2:query_text}", HttpUtility.UrlEncode(HttpUtility.UrlEncode(original_text)));
+                if (output_text.Contains("{url3:query_text}")) output_text = output_text.Replace("{url3:query_text}", HttpUtility.UrlEncode(HttpUtility.UrlEncode(HttpUtility.UrlEncode(original_text))));
+                if (output_text.Contains("{query_text}")) output_text = output_text.Replace("{query_text}", original_text);
+                item.output_text = output_text;
                 return item;
             }
             return null;
         }
 
+        /// <summary>
+        /// 保存关键词统计数据到Redis,用于长期数据分析
+        /// 缓存周期:6个月
+        /// </summary>
+        private static async Task SaveKeywordStatisticsAsync(int ruleId, string platform, string keyword)
+        {
+            try
+            {
+                // 6个月的秒数
+                const int sixMonthsInSeconds = 180 * 86400;
+
+                // 关键词总请求次数统计 - 按月份
+                string monthlyKey = $":keyword_stats:{platform}:{ruleId}:{DateTime.Now:yyyyMM}";
+                await RedisKit.IncrByAsync(monthlyKey);
+                await RedisKit.ExpireAsync(monthlyKey, sixMonthsInSeconds);
+
+                // 关键词总请求次数统计 - 按日
+                string dailyKey = $":keyword_stats:{platform}:{ruleId}:{DateTime.Now:yyyyMMdd}";
+                await RedisKit.IncrByAsync(dailyKey);
+                await RedisKit.ExpireAsync(dailyKey, sixMonthsInSeconds);
+
+                // 关键词总请求次数统计 - 按小时
+                string hourlyKey = $":keyword_stats:{platform}:{ruleId}:{DateTime.Now:yyyyMMddHH}";
+                await RedisKit.IncrByAsync(hourlyKey);
+                await RedisKit.ExpireAsync(hourlyKey, sixMonthsInSeconds);
+
+                // 平台维度统计
+                string platformMonthlyKey = $":keyword_stats:platform:{platform}:{DateTime.Now:yyyyMM}";
+                await RedisKit.IncrByAsync(platformMonthlyKey);
+                await RedisKit.ExpireAsync(platformMonthlyKey, sixMonthsInSeconds);
+
+                // 全局统计
+                string globalMonthlyKey = $":keyword_stats:global:{DateTime.Now:yyyyMM}";
+                await RedisKit.IncrByAsync(globalMonthlyKey);
+                await RedisKit.ExpireAsync(globalMonthlyKey, sixMonthsInSeconds);
+
+                // 记录关键词集合(用于后续查询有哪些关键词)
+                string keywordSetKey = $":keyword_stats:set:{platform}:{DateTime.Now:yyyyMM}";
+                await RedisKit.SAddAsync(keywordSetKey, keyword);
+                await RedisKit.ExpireAsync(keywordSetKey, sixMonthsInSeconds);
+            }
+            catch (Exception ex)
+            {
+                // Redis错误时记录日志但不阻塞业务
+                _ = new LoggerLibrary("OverrideRule", "KeywordStats").Info($"Keyword statistics save failed: {ex.Message}", ex.StackTrace).SaveAsync();
+            }
+        }
+
         public static void Refresh()
         {
             _cached = null;

+ 3 - 2
molilian.core/Core/taoke/UnionParseCore/UnionParseCore.cs

@@ -600,8 +600,9 @@ namespace molilian.core
                 switch (request.Type)
                 {
                     case "goods":
-                        string pattern = "sku=(\\d+)";
+                        string pattern = @"(?:sku=|sku%3D|sku%253D)(\d+)";
                         Match match = Regex.Match(content, pattern);
+
                         if (match.Success)
                         {
                             string goods_id = match.Groups[1].Value; // 返回匹配的 URL
@@ -887,7 +888,7 @@ namespace molilian.core
             switch (request.Type)
             {
                 case "goods":
-                    string pattern = "goods_id=(\\d+)";
+                    string pattern = @"(?:goods_id=|goods_id%3D|goods_id%253D)(\d+)";
                     Match match = Regex.Match(content, pattern);
                     if (match.Success)
                     {

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff