dodo hold hace 2 años
padre
commit
bedebe6e24

+ 41 - 9
molilian.api/Controllers/admin/ReportController.cs

@@ -1,16 +1,8 @@
 using molilian.core;
 using dodohold.core;
 using Microsoft.AspNetCore.Mvc;
-using Org.BouncyCastle.Ocsp;
 using System.Text.Json;
-using System.Runtime.InteropServices;
-using TencentCloud.Scf.V20180416.Models;
-using Quartz.Impl.AdoJobStore.Common;
-using TencentCloud.Gaap.V20180529.Models;
-using System.Net;
-using TencentCloud.Ie.V20200304.Models;
-using TencentCloud.Soe.V20180724.Models;
-
+using static molilian.core.ChartDataCore;
 namespace molilian.api.Controllers
 {
     [ApiController]
@@ -88,5 +80,45 @@ namespace molilian.api.Controllers
             return new APIResult(new { data = result });
         }
 
+
+        [HttpPost]
+        public ActionResult chartData([FromBody] JsonElement form)
+        {
+            var result = new ChartDataRes();
+
+            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");
+
+            DateTime stime = DateTime.MinValue;
+            if (!DateTime.TryParse(report_date[0], out stime)) return new APIResult(result);
+
+            string _report_date = stime.ToString("yyyyMMdd");
+            if (isHourtrend) _report_date = stime.ToString("yyyyMMddHH");
+
+
+
+            if (string.IsNullOrEmpty(accountName)) accountName = "tb";
+
+            switch (total_key)
+            {
+                case "tool_total":
+                    result = GetToolData(total_key, accountName, _report_date);
+                    break;
+                case "total":
+                case "parse_total":
+                case "coupon_total":
+                    result = GetTaobaoData(total_key, accountName, _report_date);
+                    break;
+                case "jd_parse_total":
+                    result = GetJdData(total_key, accountName, _report_date);
+
+                    break;
+            }
+            return new APIResult(result);
+        }
+
+
     }
 }

+ 3 - 0
molilian.api/Controllers/admin/TaobaoController.cs

@@ -8,9 +8,12 @@ using MySqlX.XDevAPI;
 using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
 namespace molilian.api.Controllers
 {
+
+
     [ApiController]
     [MyAuthorize("admin")]
     [Route("api/[controller]/[action]")]
+    [Route("coupon_api/[controller]/[action]")]
     public class TaobaoController : ControllerBase
     {
         readonly IAuthorizationProvider provider = new AdminProvider();

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

@@ -35,6 +35,7 @@ namespace molilian.api.Controllers
             var url = form.Read("url", string.Empty);
             var ip = form.Read("ip", string.Empty);
             var oaid = form.Read("oaid", string.Empty);
+            var recommand = form.Read("recommand", true);
 
             //验证签名
             if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
@@ -64,7 +65,7 @@ namespace molilian.api.Controllers
                 var bytes = new WebClientUtility().Request(url).ResponseBody;
                 img = Convert.ToBase64String(bytes);
             }
-            return await core.PromotionQueryAsync(img, oaid, ip);
+            return await core.PromotionQueryAsync(img, oaid, ip, recommand);
         }
 
 

+ 7 - 1
molilian.api/Controllers/public/TaskController.cs

@@ -250,10 +250,16 @@ namespace molilian.api.Controllers
                 //第三方老的统计
                 AlimamaPlus.DailyLogs(intervalDay);
 
+                //第三方老的统计
+                JdUnionPlus.DailyLogs(intervalDay);
+
+                ToolParsePlus.DailyLogs(intervalDay);
+
+
                 //产商统计
                 AlimamaPlus.DailyLogs(intervalDay, "parse_", "tb");
                 AlimamaPlus.DailyLogs(intervalDay, "coupon_", "tb");
-                AlimamaPlus.DailyLogs(intervalDay, "parse_", "tool");
+
             }
             catch (Exception ex)
             {

+ 56 - 0
molilian.api/Controllers/public/TestController.cs

@@ -9,6 +9,10 @@ using System.Threading;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 using TencentCloud.Soe.V20180724.Models;
 using static dodohold.core.ZTOExpress.CreateOrderArgs;
+using static Spire.Xls.Core.Spreadsheet.HTMLOptions;
+using System.Net.Http.Json;
+using System.Text.RegularExpressions;
+using System.Text;
 
 namespace molilian.api.Controllers
 {
@@ -22,6 +26,58 @@ namespace molilian.api.Controllers
         {
             _accessor = accessor;
         }
+        [HttpPost]
+        public async Task<ActionResult> test([FromForm] string jsonContent, [FromForm] string testText)
+        {
+
+            // 用于存储输出结果的StringBuilder
+            StringBuilder outputBuilder = new StringBuilder();
+
+            // 解析JSON数据
+            JsonDocument jsonDoc = JsonDocument.Parse(jsonContent);
+
+            // 获取根元素
+            JsonElement root = jsonDoc.RootElement;
+
+            // 遍历规则
+            foreach (JsonElement ruleSet in root.EnumerateArray())
+            {
+
+                string platformType = ruleSet.Read("platformType", string.Empty);
+                string supplier = ruleSet.Read("supplier", string.Empty);
+                outputBuilder.AppendLine($"平台类型: {platformType}, 供应商: {supplier}");
+
+                JsonElement pwdRules = ruleSet.GetProperty("pwdRules");
+                int idx = 0;
+                foreach (JsonElement patternElement in pwdRules.EnumerateArray())
+                {
+                    string pattern = patternElement.GetString();
+                    try
+                    {
+                        // 使用Regex类来编译正则表达式
+                        Regex compiledPattern = new Regex(pattern);
+                        if (compiledPattern.IsMatch(testText))
+                        {
+                            outputBuilder.AppendLine($"规则 {idx + 1}: 匹配\t{pattern}");
+                        }
+                        else
+                        {
+                            outputBuilder.AppendLine($"规则 {idx + 1}: 不匹配");
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        outputBuilder.AppendLine($"规则 {idx + 1}: 正则表达式错误 - {e.Message}\t{pattern}");
+                    }
+                    idx++;
+                }
+            }
+
+            outputBuilder.AppendLine("测试完成");
+
+            return Content(outputBuilder.ToString());
+        }
+
 
         [HttpGet]
         public async Task<ActionResult> ip(string ip)

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
molilian.api/Properties/PublishProfiles/https___ccr.ccs.tencentyun.com_shaobin.pubxml.user


+ 3 - 0
molilian.api/docker-compose.yml

@@ -24,3 +24,6 @@ services:
 
             # redis 内存数据库
             - RedisConfig=host.docker.internal:6379,password=ef4f629b9,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook
+            
+            - CenterDB=
+            - CenterRedis=

+ 4 - 3
molilian.core/Authorization/AccessTokenCore.cs

@@ -8,20 +8,21 @@ namespace molilian.core
         public AccessTokenDTO Get(string domain, string ticket)
         {
             string key = $"token:{ticket}";
-            return RedisHelper.Get<AccessTokenDTO>(key);
+            
+            return CenterHub.Redis.Get<AccessTokenDTO>(key);
         }
 
         public int Delete(string domain, string ticket)
         {
 
             string key = $"token:{ticket}";
-            return Convert.ToInt32(RedisHelper.Del(key));
+            return Convert.ToInt32(CenterHub.Redis.Del(key));
         }
 
         internal bool Create(AccessTokenDTO token)
         {
             string key = $"token:{token.AccessTicket}";
-            return RedisHelper.Set(key, token, 86400 * 30);
+            return CenterHub.Redis.Set(key, token, 86400 * 30);
         }
 
 

+ 33 - 0
molilian.core/Core/CenterHub.cs

@@ -0,0 +1,33 @@
+using CSRedis;
+using dodohold.core;
+using MySql.Data.MySqlClient;
+using System.Data;
+
+
+namespace molilian.core
+{
+    public partial class CenterHub
+    {
+        private static CSRedisClient _redis;
+        static CenterHub()
+        {
+            string centerRedis = Environment.GetEnvironmentVariable("CenterRedis");
+            if (string.IsNullOrEmpty(centerRedis))
+            {
+                _redis = RedisHelper.Instance;
+            }
+            else
+            {
+                _redis = RedisClientManager.GetRedisClient(centerRedis);
+            }
+        }
+
+        public static CSRedisClient Redis => _redis;
+
+        public static IDbConnection GetOpenConnection()
+        {
+            return DBContext.GetOpenConnection("CenterDB");
+        }
+    }
+}
+

+ 14 - 6
molilian.core/Core/ConfigCore.cs

@@ -15,19 +15,24 @@ namespace molilian.core
     {
         private static readonly object _lockObj = new();
         private static TkConfigDTO _cached;
+
+
         public static TkConfigDTO Get(bool force = false)
         {
             if (!force && _cached != null) return _cached;
 
             string cache_key = $"cache:tk_config";
-            var item = RedisHelper.Get<TkConfigDTO>(cache_key);
+
+
+            var item = CenterHub.Redis.Get<TkConfigDTO>(cache_key);
             if (force || item == null)
             {
                 lock (_lockObj)
                 {
-                    item = new DBContext.Table("tk_config").Get<TkConfigDTO>("id>0", new { });
+                    using var conn = CenterHub.GetOpenConnection();
+                    item = new DBContext.Table(conn, "tk_config").Get<TkConfigDTO>("id>0", new { });
                     if (item == null) return default;
-                    RedisHelper.Set(cache_key, item, 30 * 86400);
+                    CenterHub.Redis.Set(cache_key, item, 30 * 86400);
                 }
             }
             _cached = item;
@@ -35,21 +40,24 @@ namespace molilian.core
         }
         public static void Update(string ignorePercentageCity)
         {
-            new DBContext.Table("tk_config")
+            using var conn = CenterHub.GetOpenConnection();
+            new DBContext.Table(conn, "tk_config")
                 .Add("ignorePercentageCity", ignorePercentageCity)
                 .Update();
             _ = Get(true);
         }
         public static void Update(int ignorePercentage)
         {
-            new DBContext.Table("tk_config")
+            using var conn = CenterHub.GetOpenConnection();
+            new DBContext.Table(conn, "tk_config")
                 .Add("ignorePercentage", ignorePercentage)
                 .Update();
             _ = Get(true);
         }
         public static void JdUpdate(int ignorePercentage)
         {
-            new DBContext.Table("tk_config")
+            using var conn = CenterHub.GetOpenConnection();
+            new DBContext.Table(conn, "tk_config")
                 .Add("jdIgnorePercentage", ignorePercentage)
                 .Update();
             _ = Get(true);

+ 1 - 3
molilian.core/Core/EndPointCore.cs

@@ -65,9 +65,6 @@ namespace molilian.core
             return resultList;
         }
 
-
-
-
         public static async Task ProcessEndPointNodesAsync(Func<EndPointDTO, Task> nodeAction, bool force = false)
         {
             var list = List(force);
@@ -79,6 +76,7 @@ namespace molilian.core
             await Task.WhenAll(tasks);
         }
 
+
         public static async Task NotifyReload(bool onlyAccount = false, CancellationToken cancellationToken = default)
         {
             await ProcessEndPointNodesAsync(async node =>

+ 279 - 0
molilian.core/Core/admin/ChartDataCore.cs

@@ -0,0 +1,279 @@
+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;
+
+
+namespace molilian.core
+{
+    public partial class ChartDataCore
+    {
+        public class ChartDataItem
+        {
+            public string name { get; set; } = string.Empty;
+            public int value { get; set; } = 0;
+            public decimal increases { get; set; } = 0;
+        }
+        public class ChartDataRes
+        {
+            public List<ChartDataItem> data { get; set; } = [];
+            public List<ChartDataItem> data2 { get; set; } = [];
+            public int total { get; set; } = 0;
+        }
+
+        public static ChartDataRes GetJdData(string total_key, string accountName, string report_date)
+        {
+            ChartDataRes result = new();
+            total_key = "parse_total";
+            if (string.IsNullOrEmpty(accountName) || "all".Equals(accountName)) accountName = "jd";
+            string cacheKey = $":{total_key}:{accountName}:{report_date}";
+            result.total = TkLogCore.GetTotal(cacheKey);
+            if (result.total > 0)
+            {
+                string[] keys = [];
+
+                cacheKey = $":{total_key}:{accountName}:message:{report_date}";
+                string[] message_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+                var combinedKeys = keys.Union(message_keys).ToList();
+                combinedKeys.RemoveAll(item => item == "fail");
+
+                foreach (var keyname in combinedKeys)
+                {
+                    cacheKey = $":{total_key}:{accountName}:{keyname}:{report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
+                    if (value == 0) continue;
+                    result.data.Add(new ChartDataItem
+                    {
+                        name = keyname,
+                        value = value,
+                        increases = Math.Round((decimal)value / result.total * 100, 2)
+                    });
+                }
+                result.data = result.data.OrderByDescending(item => item.value).ToList();
+
+                cacheKey = $":{total_key}:{accountName}:reason:{report_date}";
+                string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+                foreach (var keyname in reason_keys)
+                {
+                    cacheKey = $":{total_key}:{accountName}:{keyname}:{report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
+                    if (value < 50) continue;
+                    result.data2.Add(new ChartDataItem
+                    {
+                        name = keyname,
+                        value = value,
+                        increases = Math.Round((decimal)value / result.total * 100, 2)
+                    });
+                }
+                result.data2 = result.data2.OrderByDescending(item => item.value).ToList();
+            }
+            return result;
+        }
+        public static ChartDataRes GetTaobaoData(string total_key, string accountName, string report_date)
+        {
+            ChartDataRes result = new();
+            if (string.IsNullOrEmpty(accountName) || "all".Equals(accountName)) accountName = "tb";
+            string cacheKey = $":{total_key}:{accountName}:{report_date}";
+            result.total = TkLogCore.GetTotal(cacheKey);
+            if (result.total > 0)
+            {
+                string[] keys = ["success"];
+
+                cacheKey = $":{total_key}:{accountName}:message:{report_date}";
+                string[] message_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+                var combinedKeys = keys.Union(message_keys).ToList();
+                combinedKeys.RemoveAll(item => item == "fail");
+                combinedKeys.RemoveAll(item => item == "OK");
+
+                foreach (var keyname in combinedKeys)
+                {
+                    cacheKey = $":{total_key}:{accountName}:{keyname}:{report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
+                    if (value == 0) continue;
+                    result.data.Add(new ChartDataItem
+                    {
+                        name = keyname,
+                        value = value,
+                        increases = Math.Round((decimal)value / result.total * 100, 2)
+                    });
+                }
+                result.data = result.data.OrderByDescending(item => item.value).ToList();
+
+                cacheKey = $":{total_key}:{accountName}:reason:{report_date}";
+                string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+                foreach (var keyname in reason_keys)
+                {
+                    cacheKey = $":{total_key}:{accountName}:{keyname}:{report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
+                    if (value < 50) continue;
+                    result.data2.Add(new ChartDataItem
+                    {
+                        name = keyname,
+                        value = value,
+                        increases = Math.Round((decimal)value / result.total * 100, 2)
+                    });
+                }
+                result.data2 = result.data2.OrderByDescending(item => item.value).ToList();
+            }
+            return result;
+        }
+
+
+        public static ChartDataRes GetToolData(string total_key, string accountName, string report_date)
+        {
+            ChartDataRes result = new();
+
+            accountName = "tool";
+            total_key = "parse_total";
+
+            string cacheKey = $":{total_key}:{accountName}:{report_date}";
+            result.total = TkLogCore.GetTotal(cacheKey);
+            if (result.total > 0)
+            {
+                string[] keys = ["bdpan", "wemeet"];
+
+                foreach (var keyname in keys)
+                {
+
+                    cacheKey = $":{total_key}:{keyname}:{report_date}";
+                    var total = TkLogCore.GetTotal(cacheKey);
+
+                    cacheKey = $":{total_key}:{keyname}:success:{report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
+                    if (value == 0) continue;
+                    result.data.Add(new ChartDataItem
+                    {
+                        name = $"{keyname}-成功",
+                        value = value,
+                        increases = Math.Round((decimal)value / total * 100, 2)
+                    });
+
+                    cacheKey = $":{total_key}:{keyname}:fail:{report_date}";
+                    value = TkLogCore.GetTotal(cacheKey);
+                    if (value == 0) continue;
+                    result.data.Add(new ChartDataItem
+                    {
+                        name = $"{keyname}-失败",
+                        value = value,
+                        increases = Math.Round((decimal)value / total * 100, 2)
+                    });
+                }
+
+                cacheKey = $":{total_key}:{accountName}:reason:{report_date}";
+                string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+                foreach (var keyname in reason_keys)
+                {
+                    cacheKey = $":{total_key}:{accountName}:{keyname}:{report_date}";
+                    int value = TkLogCore.GetTotal(cacheKey);
+                    if (value == 0) continue;
+                    result.data2.Add(new ChartDataItem
+                    {
+                        name = keyname,
+                        value = value,
+                        increases = Math.Round((decimal)value / result.total * 100, 2)
+                    });
+                }
+                result.data2 = result.data2.OrderByDescending(item => item.value).ToList();
+            }
+            return result;
+        }
+
+
+        //public static void GetTaobaoData(string accountName, string report_date)
+        //{
+        //    if (string.IsNullOrEmpty(accountName)) accountName = "tb";
+        //    if (total_key == "tool_total")
+        //    {
+        //        accountName = "tool";
+        //        total_key = "parse_total";
+
+        //        string cacheKey = $":{total_key}:{accountName}:{_report_date}";
+        //        double total = TkLogCore.GetTotal(cacheKey);
+        //        if (total > 0)
+        //        {
+        //            string[] keys = ["bdpan", "wemeet"];
+
+        //            foreach (var keyname in keys)
+        //            {
+
+        //                cacheKey = $":{total_key}:{keyname}:{_report_date}";
+        //                total = TkLogCore.GetTotal(cacheKey);
+
+        //                cacheKey = $":{total_key}:{keyname}:success:{_report_date}";
+        //                int value = TkLogCore.GetTotal(cacheKey);
+        //                if (value == 0) continue;
+        //                result.Add(new { name = $"{keyname}-成功", value, increases = Math.Round(value / total * 100, 2) });
+
+        //                cacheKey = $":{total_key}:{keyname}:fail:{_report_date}";
+        //                value = TkLogCore.GetTotal(cacheKey);
+        //                if (value == 0) continue;
+        //                result.Add(new { name = $"{keyname}-失败", value, increases = Math.Round(value / total * 100, 2) });
+        //            }
+
+        //            cacheKey = $":{total_key}:{accountName}:reason:{_report_date}";
+        //            string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+        //            foreach (var keyname in reason_keys)
+        //            {
+        //                cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
+        //                int value = TkLogCore.GetTotal(cacheKey);
+        //                if (value == 0) continue;
+        //                reason_result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
+        //            }
+        //            reason_result = reason_result.OrderByDescending(item => item.value).ToList();
+        //        }
+        //        return new APIResult(new { total, data = result, data2 = reason_result });
+        //    }
+        //    else
+        //    {
+        //        string cacheKey = $":{total_key}:{accountName}:{_report_date}";
+        //        double total = TkLogCore.GetTotal(cacheKey);
+        //        if (total > 0)
+        //        {
+        //            string[] keys = ["success"];
+
+        //            cacheKey = $":{total_key}:{accountName}:message:{_report_date}";
+        //            string[] message_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+        //            var combinedKeys = keys.Union(message_keys).ToList();
+        //            combinedKeys.RemoveAll(item => item == "fail");
+
+        //            foreach (var keyname in combinedKeys)
+        //            {
+        //                cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
+        //                int value = TkLogCore.GetTotal(cacheKey);
+        //                if (value == 0) continue;
+        //                result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
+        //            }
+        //            result = result.OrderByDescending(item => item.value).ToList();
+
+        //            cacheKey = $":{total_key}:{accountName}:reason:{_report_date}";
+        //            string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);
+
+        //            foreach (var keyname in reason_keys)
+        //            {
+        //                cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
+        //                int value = TkLogCore.GetTotal(cacheKey);
+        //                if (value < 50) continue;
+        //                reason_result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
+        //            }
+        //            reason_result = reason_result.OrderByDescending(item => item.value).ToList();
+        //        }
+        //        return new APIResult(new { total, data = result, data2 = reason_result });
+        //    }
+
+        //}
+
+
+    }
+
+}

+ 3 - 0
molilian.core/Core/taoke/OrderTrackingCore.cs

@@ -54,6 +54,7 @@ namespace molilian.core
             var result = EndPointCore.ProcessEndPointNodes<TkDataDTO>(node =>
             {
                 if (!node.is_public_api) return null;
+                if (string.IsNullOrEmpty(node.redis_server)) return null;
 
                 var redis = RedisClientManager.GetRedisClient(node.redis_server);
                 if (!string.IsNullOrEmpty(itemId))
@@ -79,6 +80,8 @@ namespace molilian.core
             await EndPointCore.ProcessEndPointNodesAsync(node =>
             {
                 if (!node.is_public_api) return Task.CompletedTask;
+                if (string.IsNullOrEmpty(node.redis_server)) return Task.CompletedTask;
+
 
                 var redis = RedisClientManager.GetRedisClient(node.redis_server);
                 redis.Del(cacheKey);

+ 52 - 1
molilian.core/Core/taoke/TkLogCore.cs

@@ -40,6 +40,8 @@ namespace molilian.core
             var result = EndPointCore.ProcessEndPointNodes<int>(node =>
             {
                 if (!node.is_public_api) return 0;
+                if (string.IsNullOrEmpty(node.redis_server)) return 0;
+
                 var redis = RedisClientManager.GetRedisClient(node.redis_server);
                 return BatchInsertLogDB(limit, redis);
             });
@@ -425,6 +427,12 @@ namespace molilian.core
                 var ts = DateTime.Now - response.create_time;
                 response.elapsedTime = (int)ts.TotalMilliseconds;
                 _ = RedisHelper.RPushAsync(queue_parse_tb_key, response);
+
+                if (response.success)
+                {
+                    _ = saveUnionCouponParseCacheAsync(response);
+                }
+
                 saveParseCache(response.channel.ToString(), response.accountId, response.accountName, response.success, response.message, response.reason);
                 if (!string.IsNullOrEmpty(response.itemId)) TkOrderTrackingCore.SaveLinkSummary(response);
 
@@ -461,6 +469,7 @@ namespace molilian.core
                 var ts = DateTime.Now - response.create_time;
                 response.elapsedTime = (int)ts.TotalMilliseconds;
                 _ = RedisHelper.RPushAsync(queue_coupon_key, response);
+
                 saveCouponCache(response.channel.ToString(), response.accountId, response.accountName, response.success, response.message, response.reason);
 
                 if (!response.success && "nologin".Equals(response.message))
@@ -574,6 +583,19 @@ namespace molilian.core
 
         }
 
+        private static async Task saveUnionCouponParseCacheAsync(TkDataDTO data)
+        {
+            string cacheKey = $":cache:parse:{data.ip}_{data.oaid}_{data.itemId}";
+            await EndPointCore.ProcessEndPointNodesAsync(node =>
+            {
+                if (!node.is_coupon_api) return Task.CompletedTask;
+                if (string.IsNullOrEmpty(node.redis_server)) return Task.CompletedTask;
+
+                var redis = RedisClientManager.GetRedisClient(node.redis_server);
+                redis.Set(cacheKey, 1, 2 * 86400);
+                return Task.CompletedTask;
+            });
+        }
 
         private static void saveParseCache(string channel, int accountId, string accountName, bool success, string message, string reason)
         {
@@ -715,9 +737,14 @@ namespace molilian.core
 
         public static int GetTotal(string keyname, bool all_node = true)
         {
+            //:coupon_total:tb:20240706
+            //:coupon_total:tb:success:20240706
+            //:coupon_total:tb:放弃转链:20240706
+
             var result = EndPointCore.ProcessEndPointNodes<int>(node =>
             {
                 if (!node.is_public_api) return 0;
+                if (string.IsNullOrEmpty(node.redis_server)) return 0;
 #if DEBUG
                 switch (node.name)
                 {
@@ -728,10 +755,16 @@ namespace molilian.core
                     case "gz":
                         node.redis_server = "8.138.110.158:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
                         break;
+                    case "coupon1":
+                        node.redis_server = "c1api.molilian.com:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
+                        break;
+                    default: return 0;
                 }
+
 #endif
                 var redis = RedisClientManager.GetRedisClient(node.redis_server);
-                return redis.Get<int>(keyname);
+                int count = redis.Get<int>(keyname);
+                return count;
             });
             return result.Sum();
         }
@@ -742,6 +775,24 @@ namespace molilian.core
             var result = EndPointCore.ProcessEndPointNodes<string[]>(node =>
             {
                 if (!node.is_public_api) return [];
+                if (string.IsNullOrEmpty(node.redis_server)) return [];
+#if DEBUG
+                switch (node.name)
+                {
+
+                    case "bj":
+                        node.redis_server = "101.200.46.46:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
+                        break;
+                    case "gz":
+                        node.redis_server = "8.138.110.158:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
+                        break;
+                    case "coupon1":
+                        node.redis_server = "c1api.molilian.com:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
+                        break;
+                    default: return [];
+                }
+#endif
+
                 var redis = RedisClientManager.GetRedisClient(node.redis_server);
 
                 string[] message_keys = redis.SMembers(keyname);

+ 2 - 0
molilian.core/Core/taoke/TkPoolCore.cs

@@ -62,6 +62,8 @@ namespace molilian.core
             var result = EndPointCore.ProcessEndPointNodes<bool>(node =>
             {
                 if (!node.is_public_api) return true;
+                if (string.IsNullOrEmpty(node.redis_server)) return true;
+
                 var redis = RedisClientManager.GetRedisClient(node.redis_server);
                 return redis.Set(cache_key, income_amt, 3 * 86400);
             });

+ 11 - 4
molilian.core/Core/taoke/UnionCouponCore.cs

@@ -48,10 +48,14 @@ namespace molilian.core
                 channel = TkChannelEnum.tb,
                 rawContent = content,
                 end_point = _end_point,
+                ip = ip,
+                oaid = oaid
             };
             try
             {
-                if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
+                string reason;
+                if (AlimamaPlus.FilterRiskLink(ip, oaid, content, out reason) ||
+                    AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out reason))
                 {
                     result.success = false;
                     result.message = "放弃转链";
@@ -60,7 +64,8 @@ namespace molilian.core
                     return new APIResult(new
                     {
                         result.success,
-                        message = "没有优惠券",
+                        result.message,
+                        result.reason,
                         channel = result.channel.ToString(),
                     });
                 }
@@ -75,7 +80,8 @@ namespace molilian.core
                     return new APIResult(new
                     {
                         result.success,
-                        message = "没有优惠券",
+                        result.message,
+                        result.reason,
                         channel = result.channel.ToString(),
                     });
                 }
@@ -124,7 +130,8 @@ namespace molilian.core
                 return new APIResult(new
                 {
                     result.success,
-                    message = "没有优惠券",
+                    result.message,
+                    result.reason,
                     channel = result?.channel.ToString(),
                 });
             }

+ 41 - 8
molilian.core/DTO/DailyLogsDTO.cs

@@ -6,16 +6,49 @@
     public class DailyLogsDTO
     {
         public int id { get; set; }
-        public DateTime log_date { get; set; }
-        public int channel { get; set; }
-        public string accountName { get; set; }
-        public int total_count { get; set; }
-        public int abandon_count { get; set; }
+        public DateTime log_date { get; set; } = DateTime.Now.Date;
+        public int channel { get; set; } = 0;
+        public int accountId { get; set; } = 0;
+        public string accountName { get; set; } = string.Empty;
+        public DateTime create_time { get; set; } = DateTime.Now;
+        public DateTime last_time { get; set; } = DateTime.Now;
+
+        public int total_count { get; set; } = 0;
+        public int abandon_count { get; set; } = 0;
         public string abandon_percentage { get; set; } = string.Empty;
-        public int success_count { get; set; }
+        public int success_count { get; set; } = 0;
         public string success_percentage { get; set; } = string.Empty;
-        public DateTime create_time { get; set; }
-        public DateTime last_time { get; set; }
+
+
+
+        public int coupon_total_count { get; set; } = 0;
+        public int coupon_abandon_count { get; set; } = 0;
+        public string coupon_abandon_percentage { get; set; } = string.Empty;
+        public int coupon_success_count { get; set; } = 0;
+        public string coupon_success_percentage { get; set; } = string.Empty;
+
+
+        public int parse_total_count { get; set; } = 0;
+        public int parse_abandon_count { get; set; } = 0;
+        public string parse_abandon_percentage { get; set; } = string.Empty;
+        public int parse_success_count { get; set; } = 0;
+        public string parse_success_percentage { get; set; } = string.Empty;
+
+
+
+        public int tool_total_count { get; set; } = 0;
+        public int tool_abandon_count { get; set; } = 0;
+        public string tool_abandon_percentage { get; set; } = string.Empty;
+        public int tool_success_count { get; set; } = 0;
+        public string tool_success_percentage { get; set; } = string.Empty;
+
+
+        public int jd_parse_total_count { get; set; } = 0;
+        public int jd_parse_abandon_count { get; set; } = 0;
+        public string jd_parse_abandon_percentage { get; set; } = string.Empty;
+        public int jd_parse_success_count { get; set; } = 0;
+        public string jd_parse_success_percentage { get; set; } = string.Empty;
+
 
 
     }

+ 1 - 0
molilian.core/DTO/Emun/TkChannelEnum.cs

@@ -6,6 +6,7 @@
         jd = 1,
         dy = 2,
 
+        tool = 100,
         wemeet = 101,
         bdpan = 102,
     }

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

@@ -16,6 +16,7 @@ namespace molilian.core
         public DateTime last_time { get; set; }
         public bool status { get; set; } = false;
         public bool is_public_api { get; set; } = false;
+        public bool is_coupon_api { get; set; } = false;
 
     }
 }

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

@@ -155,6 +155,13 @@
         public string parse_success_percentage { get; set; } = string.Empty;
 
 
+        public int jd_parse_total_count { get; set; } = 0;
+        public int jd_parse_abandon_count { get; set; } = 0;
+        public int jd_parse_success_count { get; set; } = 0;
+        public string jd_parse_abandon_percentage { get; set; } = string.Empty;
+        public string jd_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;

+ 1 - 24
molilian.core/Plus/Alimama/account.cs

@@ -1,28 +1,5 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc.Controllers;
-using Microsoft.AspNetCore.Mvc.Filters;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using dodohold.core;
-using Dataoke;
-using System.Text.RegularExpressions;
-using Org.BouncyCastle.Ocsp;
-using System.Diagnostics;
-using TencentCloud.Fmu.V20191213.Models;
-using Microsoft.VisualBasic;
-using System.Text.Json;
-using static System.Runtime.InteropServices.JavaScript.JSType;
-using TencentCloud.Cdn.V20180606.Models;
+using dodohold.core;
 using System.Net;
-using TencentCloud.Teo.V20220901.Models;
-using MySqlX.XDevAPI;
-using Spire.Pdf.Exporting.XPS.Schema;
-using COSXML.Network;
-using TencentCloud.Wedata.V20210820.Models;
-using System.Xml.Linq;
-
 
 namespace molilian.core
 {

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

@@ -17,7 +17,7 @@ namespace molilian.core
             result.channel = data.channel;
             result.success = data.success;
             result.reason = data.reason;
-            result.message = data.success ? "success" : data.message;
+            result.message = data.success ? "OK" : data.message;
             result.deeplink_url = data.deeplink_url;
             result.couponAmount = data.couponAmount;
             result.couponEffectiveStartTime = data.couponEffectiveStartTime;

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

@@ -13,12 +13,13 @@ namespace molilian.core
         /// <param name="intervalDay"></param>
         public static void DailyLogs(int intervalDay, string prefix = "", string channel = "all")
         {
-
-            var db_prefix = prefix;
-            if (channel == "tool")
+            int channelId = (int)TkChannelEnum.tb;
+            var db_prefix = channel switch
             {
-                db_prefix = "tool_";
-            }
+                "tool" => "tool_",
+                "jd" => "jd_parse_",
+                _ => prefix,
+            };
 
             DateTime log_date = DateTime.Now.AddDays(-intervalDay).Date;
 
@@ -48,7 +49,7 @@ namespace molilian.core
 
                 var exist = new DBContext.Table("daily_logs")
                      .Fields("id,log_date")
-                     .Get<dynamic>("log_date=@log_date AND accountId=@accountId", new { log_date, accountId });
+                     .Get<dynamic>("log_date=@log_date AND channel=@channel AND accountId=@accountId", new { log_date, channel = channelId, accountId });
 
 
                 var createArgs = new DBContext.Table("daily_logs")
@@ -62,7 +63,7 @@ namespace molilian.core
 
                 if (exist == null)
                 {
-                    createArgs.Add("channel", 0)
+                    createArgs.Add("channel", channelId)
                         .Add("accountId", accountId)
                         .Add("accountName", account.company)
                         .Add("log_date", log_date)
@@ -75,7 +76,6 @@ namespace molilian.core
                 }
             }
 
-
             int all_total_count = TkLogCore.GetTotal($":{prefix}total:{channel}:{log_date:yyyyMMdd}");
             var all_success_count = TkLogCore.GetTotal($":{prefix}total:{channel}:success:{log_date:yyyyMMdd}");
             var all_abandon_count = TkLogCore.GetTotal($":{prefix}total:{channel}:放弃转链:{log_date:yyyyMMdd}");
@@ -87,10 +87,10 @@ namespace molilian.core
                 all_success_percentage = $"{all_success_count / (double)all_total_count * 100:f2}%";
                 all_abandon_percentage = $"{all_abandon_count / (double)all_total_count * 100:f2}%";
             }
-
             var exist2 = new DBContext.Table("daily_logs")
                  .Fields("id,log_date")
-                 .Get<dynamic>("log_date=@log_date AND accountId=@accountId", new { log_date, accountId = 0 });
+                 .Get<dynamic>("log_date=@log_date AND channel=@channel AND accountId=@accountId",
+                 new { log_date, channel = channelId, accountId = 0 });
 
             var createArgs2 = new DBContext.Table("daily_logs")
                 .Add($"{db_prefix}total_count", all_total_count)
@@ -102,7 +102,7 @@ namespace molilian.core
 
             if (exist2 == null)
             {
-                createArgs2.Add("channel", 0)
+                createArgs2.Add("channel", channelId)
                     .Add("accountId", 0)
                     .Add("accountName", "all")
                     .Add("log_date", log_date)

+ 17 - 0
molilian.core/Plus/Alimama/parse.cs

@@ -6,6 +6,7 @@ using System.Linq;
 using System.Security.Cryptography;
 using TencentCloud.Ecm.V20190719.Models;
 using System.Diagnostics;
+using static dodohold.core.ZTOExpress.CreateOrderArgs;
 
 namespace molilian.core
 {
@@ -414,12 +415,28 @@ namespace molilian.core
             }
             return matchCount >= 2;
         }
+        public static bool FilterRiskLink(string ip, string oaid, string content, out string reason)
+        {
+            reason = string.Empty;
+            string itemId = ExtractItemId(content);
+            if (string.IsNullOrEmpty(itemId)) return false;
+
+            string cacheKey = $":cache:parse:{ip}_{oaid}_{itemId}";
+            int flag = RedisHelper.Get<int>(cacheKey);
+            if (flag > 0)
+            {
+                reason = $"口令用户";
+                return true;
+            }
+            return false;
+        }
 
         public static bool ShouldIgnoreRequest(string ip, string oaid, out string reason)
         {
             reason = string.Empty;
             try
             {
+
                 // IP和流量控制
                 var config = TkConfigCore.Get();
                 string ignorePercentageCity = config.ignorePercentageCity;

+ 3 - 1
molilian.core/Plus/Alimama/parse_2.cs

@@ -72,7 +72,7 @@ namespace molilian.core
         /// </summary>
         /// <param name="url"></param>
         /// <returns></returns>
-        static string? ExtractItemId(string url)
+        public static string? ExtractItemId(string url)
         {
             Match match = Regex.Match(url, @"(?:\?|&)id=(\d+)");
             if (match.Success)
@@ -638,6 +638,8 @@ namespace molilian.core
                 string sellerNickName = root.PathRead("data.sellerNickName", string.Empty);
                 string shopTitle = root.PathRead("data.shopTitle", string.Empty);
                 string pic = root.PathRead("data.pic", string.Empty);
+                if (pic.StartsWith("//")) pic = "https:" + pic;
+
                 string qrCodeUrl = root.PathRead("data.qrCodeUrl", string.Empty);
 
 

+ 126 - 0
molilian.core/Plus/JDUnion/JdDailyLogs.cs

@@ -0,0 +1,126 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Controllers;
+using Microsoft.AspNetCore.Mvc.Filters;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using dodohold.core;
+using Dataoke;
+using System.Text.RegularExpressions;
+using Org.BouncyCastle.Ocsp;
+using System.Diagnostics;
+using TencentCloud.Fmu.V20191213.Models;
+using Microsoft.VisualBasic;
+using System.Text.Json;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+using System.Security.Cryptography;
+using Google.Protobuf.WellKnownTypes;
+using Microsoft.Extensions.FileSystemGlobbing.Internal;
+using System.Threading.Channels;
+
+
+namespace molilian.core
+{
+    public partial class JdUnionPlus
+    {
+        public static void DailyLogs(int intervalDay)
+        {
+            TkChannelEnum channelEnum = TkChannelEnum.jd;
+
+            DateTime log_date = DateTime.Now.AddDays(-intervalDay).Date;
+
+            var accounts = JdPoolCore.List();
+            foreach (var account in accounts)
+            {
+                int accountId = account.id;
+                string accountName = $"{channelEnum}_{account.id}";
+
+                int total_count = TkLogCore.GetTotal($":parse_total:{accountName}:{log_date:yyyyMMdd}");
+                if (total_count == 0) accountName = account.name;
+
+                total_count = TkLogCore.GetTotal($":parse_total:{accountName}:{log_date:yyyyMMdd}");
+                if (total_count == 0) continue;
+
+                var success_count = TkLogCore.GetTotal($":parse_total:{accountName}:success:{log_date:yyyyMMdd}");
+                var abandon_count = TkLogCore.GetTotal($":parse_total:{accountName}:放弃转链:{log_date:yyyyMMdd}");
+                string success_percentage = string.Empty;
+                string abandon_percentage = string.Empty;
+
+                if (total_count > 0)
+                {
+                    success_percentage = $"{success_count / (double)total_count * 100:f2}%";
+                    abandon_percentage = $"{abandon_count / (double)total_count * 100:f2}%";
+                }
+
+                var exist = new DBContext.Table("daily_logs")
+                .Fields("id,log_date")
+                     .Get<dynamic>("log_date=@log_date AND channel=@channel AND accountId=@accountId",
+                     new { log_date, channel = (int)channelEnum, accountId });
+
+
+                var createArgs = new DBContext.Table("daily_logs")
+                    .Add($"jd_parse_total_count", total_count)
+                    .Add($"jd_parse_abandon_count", abandon_count)
+                    .Add($"jd_parse_abandon_percentage", abandon_percentage)
+                    .Add($"jd_parse_success_count", success_count)
+                    .Add($"jd_parse_success_percentage", success_percentage)
+                    .Add("last_time", DateTime.Now);
+
+                if (exist == null)
+                {
+                    createArgs.Add("channel", (int)channelEnum)
+                        .Add("accountId", accountId)
+                        .Add("accountName", account.name)
+                        .Add("log_date", log_date)
+                        .Add("create_time", DateTime.Now)
+                        .Create();
+                }
+                else
+                {
+                    createArgs.Where("id=@id", new { exist.id }).Update();
+                }
+            }
+
+            int all_total_count = TkLogCore.GetTotal($":parse_total:{channelEnum}:{log_date:yyyyMMdd}");
+            var all_success_count = TkLogCore.GetTotal($":parse_total:{channelEnum}:success:{log_date:yyyyMMdd}");
+            var all_abandon_count = TkLogCore.GetTotal($":parse_total:{channelEnum}:放弃转链:{log_date:yyyyMMdd}");
+
+            string all_success_percentage = string.Empty;
+            string all_abandon_percentage = string.Empty;
+            if (all_total_count > 0)
+            {
+                all_success_percentage = $"{all_success_count / (double)all_total_count * 100:f2}%";
+                all_abandon_percentage = $"{all_abandon_count / (double)all_total_count * 100:f2}%";
+            }
+            var exist2 = new DBContext.Table("daily_logs")
+            .Fields("id,log_date")
+                 .Get<dynamic>("log_date=@log_date AND accountId=@accountId",
+                 new { log_date, accountId = 0 });
+
+            var createArgs2 = new DBContext.Table("daily_logs")
+                .Add($"jd_parse_total_count", all_total_count)
+                .Add($"jd_parse_abandon_count", all_abandon_count)
+                .Add($"jd_parse_abandon_percentage", all_abandon_percentage)
+                .Add($"jd_parse_success_count", all_success_count)
+                .Add($"jd_parse_success_percentage", all_success_percentage)
+                .Add("last_time", DateTime.Now);
+
+            if (exist2 == null)
+            {
+                createArgs2.Add("channel", (int)channelEnum)
+                    .Add("accountId", 0)
+                    .Add("accountName", "all")
+                    .Add("log_date", log_date)
+                    .Add("create_time", DateTime.Now)
+                    .Create();
+            }
+            else
+            {
+                createArgs2.Where("id=@id", new { exist2.id }).Update();
+            }
+
+        }
+
+    }
+}

+ 82 - 0
molilian.core/Plus/Tool/ToolDailyLogs.cs

@@ -0,0 +1,82 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Controllers;
+using Microsoft.AspNetCore.Mvc.Filters;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using dodohold.core;
+using Dataoke;
+using System.Text.RegularExpressions;
+using Org.BouncyCastle.Ocsp;
+using System.Diagnostics;
+using TencentCloud.Fmu.V20191213.Models;
+using Microsoft.VisualBasic;
+using System.Text.Json;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+using System.Security.Cryptography;
+using Google.Protobuf.WellKnownTypes;
+using Microsoft.Extensions.FileSystemGlobbing.Internal;
+
+
+namespace molilian.core
+{
+    public partial class ToolParsePlus
+    {
+        public static void DailyLogs(int intervalDay)
+        {
+            TkChannelEnum toolChannelEnum = TkChannelEnum.tool;
+            string channel = toolChannelEnum.ToString();
+
+            DateTime log_date = DateTime.Now.AddDays(-intervalDay).Date;
+
+            int all_total_count = 0;
+            var all_success_count = 0;
+            var all_abandon_count = 0;
+            List<TkChannelEnum> arr = [TkChannelEnum.wemeet, TkChannelEnum.bdpan];
+            foreach (var channelEnum in arr)
+            {
+                all_total_count += TkLogCore.GetTotal($":parse_total:{channel}:{log_date:yyyyMMdd}");
+                all_success_count += TkLogCore.GetTotal($":parse_total:{channel}:success:{log_date:yyyyMMdd}");
+                all_abandon_count += TkLogCore.GetTotal($":parse_total:{channel}:放弃转链:{log_date:yyyyMMdd}");
+            }
+
+            string all_success_percentage = string.Empty;
+            string all_abandon_percentage = string.Empty;
+            if (all_total_count > 0)
+            {
+                all_success_percentage = $"{all_success_count / (double)all_total_count * 100:f2}%";
+                all_abandon_percentage = $"{all_abandon_count / (double)all_total_count * 100:f2}%";
+            }
+
+            var exist = new DBContext.Table("daily_logs")
+            .Fields("id,log_date")
+                 .Get<dynamic>("log_date=@log_date AND accountId=@accountId",
+                 new { log_date, accountId = 0 });
+
+            var createArgs2 = new DBContext.Table("daily_logs")
+                .Add($"tool_total_count", all_total_count)
+                .Add($"tool_abandon_count", all_abandon_count)
+                .Add($"tool_abandon_percentage", all_abandon_percentage)
+                .Add($"tool_success_count", all_success_count)
+                .Add($"tool_success_percentage", all_success_percentage)
+                .Add("last_time", DateTime.Now);
+
+            if (exist == null)
+            {
+                createArgs2.Add("channel", (int)toolChannelEnum)
+                    .Add("accountId", 0)
+                    .Add("accountName", "all")
+                    .Add("log_date", log_date)
+                    .Add("create_time", DateTime.Now)
+                    .Create();
+            }
+            else
+            {
+                createArgs2.Where("id=@id", new { exist.id }).Update();
+            }
+
+        }
+
+    }
+}

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio