瀏覽代碼

文本覆盖规则

dodo hold 10 月之前
父節點
當前提交
1b1edd36db

+ 122 - 0
molilian.api/Controllers/admin/OverrideRulesController.cs

@@ -0,0 +1,122 @@
+using molilian.core;
+using dodohold.core;
+using Microsoft.AspNetCore.Mvc;
+using System.Text.Json;
+using System.Net;
+using static QRCoder.PayloadGenerator;
+using MySqlX.XDevAPI;
+using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
+using StackExchange.Redis;
+namespace molilian.api.Controllers
+{
+
+
+    [ApiController]
+    [MyAuthorize("admin")]
+    [Route("api/[controller]/[action]")]
+    public class OverrideRulesController : ControllerBase
+    {
+        readonly IAuthorizationProvider provider = new AdminProvider();
+        protected IHttpContextAccessor _accessor;
+        public OverrideRulesController(IHttpContextAccessor accessor)
+        {
+            _accessor = accessor;
+        }
+
+
+
+        [HttpPost]
+        public ActionResult list([FromBody] JsonElement form)
+        {
+            var token = provider.Get(_accessor.HttpContext);
+
+            int page = form.Read("current", 1);
+            int size = form.Read("pageSize", 10);
+            bool getTotal = form.Read("getTotal", true);
+
+            string sort = form.Read<string>("sort");
+            string order = form.Read<string>("order");
+
+            string filter = string.Empty;
+
+            var keyword = form.Read("keyword", string.Empty);
+
+            if (!string.IsNullOrEmpty(keyword))
+            {
+                filter += $" AND (original_text like @keyword OR original_text like @keyword)";
+                keyword = $"%{keyword}%";
+            }
+            filter = filter.StringTrimStart(" AND ");
+
+            string orderBy = "sort DESC, id DESC";
+            if (!string.IsNullOrEmpty(order))
+            {
+                order = "descending".Equals(order) ? "DESC" : "ASC";
+                orderBy = sort switch
+                {
+                    _ => $"{sort} {order}",
+                };
+            }
+
+            var result = new DBContext.Table("tk_override_rules")
+               .Where(filter, new { keyword })
+               .Page(size, page)
+               .Order(orderBy)
+               .PageList<dynamic>(getTotal);
+
+            return new APIResult(new { data = result });
+        }
+
+
+
+        [HttpPost]
+        public async Task<ActionResult> update([FromBody] OverrideRuleDTO data)
+        {
+            var clientIp = _accessor.HttpContext.GetUserIp();
+            var token = provider.Get(_accessor.HttpContext);
+
+            using var conn = DBContext.GetOpenConnection();
+            if (data.id == 0) return new APIResult(new { data = new { success = false, msg = "更新失败,请检查输入参数" } });
+
+            var item = new DBContext.Table(conn, "tk_override_rules").Get<OverrideRuleDTO>("id=@id", new { data.id });
+            if (item == null) return new APIResult(new { data = new { success = false, msg = "更新失败,记录不存在" } });
+
+            data.last_time = DateTime.Now;
+            var result = OverrideRuleCore.Update(data, conn);
+            bool success = result > 0;
+            if (success)
+            {
+                string desc = ObjectComparer.PrintCompareToString(item, data).Trim();
+                OperationLogCore.LogOperation(token.AccessKey, clientIp, $"tk_override_rules:{data.id}", item.Convert2Json(), desc);
+            }
+            return new APIResult(new
+            {
+                data = new { success, msg = success ? "更新成功" : "更新失败,请检查输入信息" },
+            });
+        }
+
+        [HttpPost]
+        public async Task<ActionResult> create([FromBody] OverrideRuleDTO data)
+        {
+            var clientIp = _accessor.HttpContext.GetUserIp();
+            var token = provider.Get(_accessor.HttpContext);
+
+            data.create_time = DateTime.Now;
+            data.last_time = DateTime.Now;
+
+            using var conn = DBContext.GetOpenConnection();
+            var result = OverrideRuleCore.Create(data, conn);
+            bool success = result > 0;
+            if (success)
+            {
+                OperationLogCore.LogOperation(token.AccessKey, clientIp, $"tk_override_rules:{result}", string.Empty, data.Convert2Json());
+            }
+            return new APIResult(new
+            {
+                data = new { success, msg = success ? "更新成功" : "更新失败,请检查输入信息" },
+            });
+        }
+
+
+    }
+}

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

@@ -1127,6 +1127,7 @@ namespace molilian.api.Controllers
             CpsPoolCore.Refresh();
             DeeplinkParseRuleCore.Refresh();
 
+            OverrideRuleCore.Refresh();
             return new APIResult(new
             {
                 success = true,
@@ -1148,6 +1149,8 @@ namespace molilian.api.Controllers
             //ElePoolCore.Refresh();
             //MeituanPoolCore.Refresh();
             CpsPoolCore.Refresh();
+
+            OverrideRuleCore.Refresh();
             return new APIResult(new
             {
                 success = true,

文件差異過大導致無法顯示
+ 0 - 0
molilian.api/Properties/PublishProfiles/latest.pubxml.user


+ 2 - 2
molilian.api/Properties/launchSettings.json

@@ -4,7 +4,7 @@
       "commandName": "Project",
       "launchBrowser": true,
       "launchUrl": "swagger",
-      "environmentVariables": {
+      "environmentVariables2": {
         "ASPNETCORE_ENVIRONMENT": "Development",
         "EndPoint": "coupon",
         "NtfyServer": "https://ntfy.yunhui800.com/vozQub8a78ABLqqY",
@@ -16,7 +16,7 @@
         "CenterDB": "",
         "CenterRedis": ""
       },
-      "environmentVariables2": {
+      "environmentVariables": {
         "ASPNETCORE_ENVIRONMENT": "Development",
         "EndPoint": "bj",
         "NtfyServer": "https://ntfy.yunhui800.com/5Sq9BytXXM5WDY3G",

+ 138 - 0
molilian.core/Core/OverrideRuleCore.cs

@@ -0,0 +1,138 @@
+using dodohold.core;
+using System.Data;
+using System.Text.RegularExpressions;
+using YunhuiKit;
+
+
+namespace molilian.core
+{
+
+    public partial class OverrideRuleCore
+    {
+
+        private static IEnumerable<OverrideRuleDTO> _cached;
+
+        private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
+
+        public static async Task<IEnumerable<OverrideRuleDTO>> ListAsync(bool force = false)
+        {
+            if (!force && _cached != null) return _cached;
+            try
+            {
+                await _semaphore.WaitAsync();
+
+                // 如果缓存存在且未强制刷新,直接返回
+                if (!force && _cached != null) return _cached;
+
+                string cache_key = $"cache:tk_override_rules";
+                IEnumerable<OverrideRuleDTO>? list = null;
+
+                // 尝试从Redis获取数据
+                try
+                {
+                    list = await RedisKit.GetAsync<IEnumerable<OverrideRuleDTO>>(cache_key);
+                }
+                catch (Exception ex)
+                {
+                    // 记录Redis错误
+                    _ = new LoggerLibrary("OverrideRule", "Redis").Info(ex.Message, ex.StackTrace).SaveAsync();
+                }
+
+                // 如果Redis获取失败或需要强制刷新
+                if (force || list == null)
+                {
+                    try
+                    {
+                        list = new DBContext.Table("tk_override_rules")
+                            .Where("status=@status", new { status = 1 })
+                            .Order("sort DESC, id DESC")
+                            .Select<OverrideRuleDTO>();
+
+                        if (list != null && list.Any())
+                        {
+                            // 尝试更新Redis缓存
+                            try
+                            {
+                                await RedisKit.SetAsync(cache_key, list, 30 * 86400);
+                            }
+                            catch (Exception ex)
+                            {
+                                // 记录Redis更新错误
+                                _ = new LoggerLibrary("OverrideRule", "Redis").Info(ex.Message, ex.StackTrace).SaveAsync();
+                            }
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        // 记录数据库查询错误
+                        _ = new LoggerLibrary("OverrideRule", "Database").Info(ex.Message, ex.StackTrace).SaveAsync();
+
+                        // 如果数据库查询失败但缓存还在,继续使用缓存
+                        if (_cached != null) return _cached;
+                        throw; // 如果没有任何可用数据,则抛出异常
+                    }
+                }
+                _cached = list;
+                return list ?? [];
+            }
+            finally
+            {
+                _semaphore.Release();
+            }
+        }
+
+        public static async Task<OverrideRuleDTO> ProcessAsync(string content)
+        {
+            var list = await ListAsync();
+
+            foreach (var item in list)
+            {
+                if (!"tk".Equals(item.platform)) continue;
+                if (string.IsNullOrEmpty(item.original_text)) continue;
+
+                switch (item.rule)
+                {
+                    case "regex":
+                        Match match = Regex.Match(content, item.original_text);
+                        if (!match.Success) continue;
+                        return item;
+                    default:
+                        if (!content.Contains(item.original_text)) continue;
+                        return item;
+                }
+            }
+            return null;
+        }
+
+        public static void Refresh()
+        {
+            _cached = null;
+            _ = ListAsync(true);
+        }
+
+
+        public static int Update(OverrideRuleDTO data, IDbConnection conn)
+        {
+            var result = (int)conn.Update<OverrideRuleDTO>(data, new { data.id });
+            _ = ListAsync(true);
+#if DEBUG
+#else
+            EndPointCore.NotifyReload();
+#endif
+            return result;
+        }
+
+        public static int Create(OverrideRuleDTO data, IDbConnection conn)
+        {
+            var result = (int)conn.Insert(data);
+            _ = ListAsync(true);
+#if DEBUG
+#else
+            EndPointCore.NotifyReload();
+#endif
+            return result;
+        }
+
+
+    }
+}

+ 43 - 0
molilian.core/Core/taoke/UnionParseCore/UnionParseCore.cs

@@ -185,6 +185,40 @@ namespace molilian.core
                 bool is_other = AlimamaPlus.MatchOtherInfo(content, arr2);
 
 
+                var overrideContent = await OverrideRuleCore.ProcessAsync(content);
+                if (overrideContent != null)
+                {
+                    bool is_ignore = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, riskStrategy, launchScene, out reason);
+                    if (is_ignore)
+                    {
+                        result.success = false;
+                        result.message = "放弃转链";
+                        result.itemName = "点击打开淘宝APP";
+                        result.reason = reason;
+                        result.subCode = TkSubCodeEnum.TrafficCtrl;
+
+                    }
+                    else
+                    {
+                        result.success = true;
+                        result.deeplink_url = overrideContent.output_text;
+                    }
+
+                    return TaobaoParseOutput(result, swData, new
+                    {
+                        result.success,
+                        result.commercial,
+                        result.message,
+                        sub_message = result.reason,
+                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
+                        result.content,
+                        result.itemName,
+                        other_aff,
+                        result.deeplink_url,
+                    });
+                }
+
+
                 //============================== 放弃转链-初步筛选1 ==============================
                 if (!is_tao_url && !is_tao_token || is_other)
                 {
@@ -826,6 +860,15 @@ namespace molilian.core
                         //https://mobile.yangkeduo.com/goods.html?_wv=41729&_wvx=10&goods_id=665746260825
                         content = $"https://mobile.yangkeduo.com/goods.html?goods_id={goods_id}";
                     }
+                    else
+                    {
+                        result.success = false;
+                        result.deeplink_url = string.Empty;
+                        result.message = "放弃转链";
+                        result.reason = "无效商品ID";
+                        _ = TkLogCore.ParseLogAsync(result);
+                        return PddParseOutput(result);
+                    }
                     break;
                 default:
                     content = content.UrlDecode();

+ 27 - 0
molilian.core/DTO/OverrideRuleDTO.cs

@@ -0,0 +1,27 @@
+using dodohold.core;
+using System.Text.Json.Serialization;
+using YunhuiKit;
+
+namespace molilian.core
+{
+    [Table("tk_override_rules")]
+    public class OverrideRuleDTO
+    {
+        [Key]
+
+        public int id { get; set; }
+        public string platform { get; set; } = string.Empty;
+        public string original_text { get; set; } = string.Empty;
+        public string rule { get; set; } = string.Empty;
+        public string output_text { get; set; } = string.Empty;
+        public string output_type { get; set; } = string.Empty;
+        [JsonConverter(typeof(NumericBooleanConverter))]
+        public bool status { get; set; }
+        [IgnoreUpdate]
+        [JsonConverter(typeof(NullableDateTimeConverter))]
+        public DateTime create_time { get; set; }
+        [JsonConverter(typeof(NullableDateTimeConverter))]
+        public DateTime last_time { get; set; }
+
+    }
+}

部分文件因文件數量過多而無法顯示