Explorar el Código

京东返回的d 可以通过后台配置

dodo hold hace 1 año
padre
commit
5bcab23b33
Se han modificado 40 ficheros con 699 adiciones y 128 borrados
  1. 5 5
      molilian.api/Controllers/admin/TaobaoController.cs
  2. 1 1
      molilian.api/Controllers/admin/UserController.cs
  3. 44 0
      molilian.api/Controllers/public/TaskController.cs
  4. 18 13
      molilian.api/Controllers/public/TestController.cs
  5. 10 5
      molilian.api/Controllers/public/TkController.cs
  6. 0 0
      molilian.api/Properties/PublishProfiles/latest.pubxml.user
  7. 16 4
      molilian.api/Properties/launchSettings.json
  8. 1 1
      molilian.api/molilian.api.csproj
  9. 4 3
      molilian.core/Authorization/Provider/APIProvider.cs
  10. 4 3
      molilian.core/Authorization/Provider/AdminProvider.cs
  11. 4 3
      molilian.core/Authorization/Provider/UserProvider.cs
  12. 25 1
      molilian.core/Core/ProxyNodesCore.cs
  13. 143 2
      molilian.core/Core/aliyun/AliyunCore.cs
  14. 2 2
      molilian.core/Core/dataoke/DataokeCore.cs
  15. 1 2
      molilian.core/Core/jd/JdPoolCore.cs
  16. 1 1
      molilian.core/Core/ks/KsPoolCore.cs
  17. 4 4
      molilian.core/Core/log/base.cs
  18. 35 1
      molilian.core/Core/log/jd.cs
  19. 1 0
      molilian.core/Core/log/promotion.cs
  20. 1 0
      molilian.core/Core/log/taobao.cs
  21. 1 1
      molilian.core/Core/pdd/PddPoolCore.cs
  22. 33 5
      molilian.core/Core/taoke/OrderTrackingCore.cs
  23. 1 1
      molilian.core/Core/taoke/RiskControlCore.cs
  24. 35 1
      molilian.core/Core/taoke/TaokeOpenCore.cs
  25. 4 4
      molilian.core/Core/taoke/UnionCouponCore.cs
  26. 16 15
      molilian.core/Core/taoke/UnionParseCore.cs
  27. 1 0
      molilian.core/DTO/alimama/PromotionQueryDTO.cs
  28. 3 0
      molilian.core/DTO/alimama/TkConfigDTO.cs
  29. 1 0
      molilian.core/DTO/alimama/TkDataDTO.cs
  30. 1 0
      molilian.core/DTO/alimama/TkOrderTrackingDTO.cs
  31. 32 12
      molilian.core/Plus/Alimama/orders.cs
  32. 3 3
      molilian.core/Plus/Alimama/parse.cs
  33. 3 1
      molilian.core/Plus/Alimama/parse_2.cs
  34. 49 2
      molilian.core/Plus/Aliyun/Vpc.cs
  35. 1 1
      molilian.core/Plus/JDUnion/H5stHack.cs
  36. 42 14
      molilian.core/Plus/JDUnion/JdUnionPlus.cs
  37. 2 2
      molilian.core/Plus/JDUnion/coupon.cs
  38. 14 14
      molilian.core/Plus/JDUnion/goods.cs
  39. 136 0
      molilian.core/Plus/VeapiPlus.cs
  40. 1 1
      molilian.core/molilian.core.csproj

+ 5 - 5
molilian.api/Controllers/admin/TaobaoController.cs

@@ -331,12 +331,12 @@ namespace molilian.api.Controllers
             string order = form.Read<string>("order");
 
             var report_date = form.PathReadArray<string>("query_date[]");
-            int accountId = form.Read("accountId", 0);
+            string accountName = form.Read<string>("accountName");
 
             string filter = string.Empty;
-            if (accountId != 0)
+            if (!string.IsNullOrEmpty(accountName))
             {
-                filter += $" AND accountId=@accountId";
+                filter += $" AND accountName=@accountName";
             }
 
             DateTime stime = DateTime.MinValue, etime = DateTime.MinValue;
@@ -363,7 +363,7 @@ namespace molilian.api.Controllers
             }
 
             var result = new DBContext.Table("tk_report")
-                .Where(filter, new { accountId, stime, etime })
+                .Where(filter, new { accountName, stime, etime })
                 .Page(size, page)
                 .Order(orderBy)
                 .PageList<TkReportDTO>(getTotal);
@@ -378,7 +378,7 @@ namespace molilian.api.Controllers
 #endif
                 //var tk = TkPoolCore.GetOne(item.accountId);
                 //if (tk != null) item.accountName = tk.company;
-                string accountName = $"{TkChannelEnum.tb}_{item.accountId}";
+                accountName = $"{TkChannelEnum.tb}_{item.accountId}";
 
                 if (item.total_count == 0)
                 {

+ 1 - 1
molilian.api/Controllers/admin/UserController.cs

@@ -40,7 +40,7 @@ namespace molilian.api.Controllers
             if (!dbPassword.Equals(pwd)) return new APIResult(new { msg = "账号密码不正确" }, APIResultCodeEnum.InvalidRequest);
 
             //检查登录,然后发布token
-            var accessToken = provider.Create(user.id, username, password, user.roles, domain, _accessor.HttpContext.GetUserIp());
+            var accessToken = provider.Create(user.id, username, password, user.roles, string.Empty, domain, _accessor.HttpContext.GetUserIp());
             if (accessToken == null)
             {
                 return new APIResult(new { msg = "账号/密码无效或已被禁用" }, APIResultCodeEnum.InvalidRequest);

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

@@ -11,6 +11,7 @@ using COSXML.Network;
 using System.Security.Cryptography;
 using System.Threading;
 using TencentCloud.Batch.V20170312.Models;
+using Org.BouncyCastle.Bcpg.OpenPgp;
 
 namespace molilian.api.Controllers
 {
@@ -27,6 +28,49 @@ namespace molilian.api.Controllers
 
 
 
+        [HttpGet]
+        public async Task<ActionResult> GetRawItemIdTask(int limit = 100)
+        {
+            var list = TkPoolCore.List();
+            if (list == null) return new APIResult(new { success = false, message = "没有有效账号", });
+            string message = string.Empty;
+            int total = 0;
+            foreach (var account in list)
+            {
+                if (!account.enable_sync_order) continue;
+                int accountId = account.id;
+
+                DateTime create_time = DateTime.Now.AddDays(-2);
+                string filter = "accountId=@accountId AND create_time>@create_time AND itemId IS NULL";
+                var order_list = new DBContext.Table("tk_order_details")
+                      .Where(filter, new { accountId, create_time })
+                      .Order("create_time")
+                      .Limit(limit)
+                      .Select<TkOrderDetailDTO>();
+                if (!order_list.Any()) continue;
+
+                var alimama = new AlimamaPlus(account);
+
+                foreach (var item in order_list)
+                {
+                    string mktId = item.mktId;
+                    //进行订单和转链匹配
+                    (int state, string itemId) = alimama.GetRawItemId(mktId);
+                    if (state == -1) return new APIResult(new { success = false, message = "有账号掉线了", });
+                    if (string.IsNullOrEmpty(itemId)) continue;
+
+                    item.itemId = itemId;
+                    new DBContext.Table("tk_order_details")
+                        .Add("itemId", itemId)
+                        .Where("id=@id", new { item.id })
+                        .Update();
+                    TkOrderTrackingCore.MatchOrder(account, item, null);
+                }
+            }
+            return new APIResult(new { success = true, message = "ok", limit, total });
+        }
+
+
         [HttpGet]
         public async Task<ActionResult> BatchInsertLogDB(int limit = 100)
         {

+ 18 - 13
molilian.api/Controllers/public/TestController.cs

@@ -28,24 +28,29 @@ namespace molilian.api.Controllers
             _accessor = accessor;
         }
 
+
         [HttpGet]
-        public async Task<ActionResult> ReleaseEipAddress(int id, string allocationId)
+        public async Task<ActionResult> ChangePublicIp(int id)
         {
-            AliyunCore core = new AliyunCore(id);
-            var success = core.ReleaseEipAddress("cn-beijing", allocationId);
-            return new APIResult(new { success });
-        }
+            id = id >= 20000 ? id - 20000 : id;
 
+            var proxy_node = new DBContext.Table("proxy_nodes").Get<dynamic>(id);
+            if (proxy_node == null) return new APIResult(new { success = false, msg = "没有匹配的 proxy_nodes 记录" });
 
-        //[HttpGet]
-        //public async Task<ActionResult> ChangePublicIp(int id, string ecsid, string privateIp)
-        //{
-        //    AliyunCore core = new AliyunCore(id);
-        //    //创建弹性网卡并绑定公网IP
-        //    var success = core.ChangePublicIp("cn-beijing", ecsid, privateIp);
+            int aliyun_id = proxy_node.aliyun_id;
+            string proxy_server = proxy_node.server;
 
-        //    return new APIResult(new { success });
-        //}
+            var account = new DBContext.Table("aliyun_pool").Get<dynamic>(aliyun_id);
+            if (account == null) return new APIResult(new { success = false, msg = "没有匹配的 aliyun_pool 记录" });
+
+
+
+            var uri = new Uri(proxy_server);
+            string privateIp = uri.Host;
+            AliyunCore core = new AliyunCore(account.id);
+            var success = core.ChangePublicIp(privateIp);
+            return new APIResult(new { success = "ok" });
+        }
 
 
 

+ 10 - 5
molilian.api/Controllers/public/TkController.cs

@@ -47,6 +47,7 @@ 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);
+            var clickId = form.Read("clickId", string.Empty);
             var commerceType = form.Read<int>("commerceType", 0);
 
 
@@ -72,7 +73,7 @@ namespace molilian.api.Controllers
             {
                 return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
             }
-            return await UnionParseCore.UnionParseAsync(content, channel, commerceType, ip, oaid);
+            return await UnionParseCore.UnionParseAsync(content, channel, commerceType, ip, oaid, 0, clickId);
         }
 
         [HttpPost]
@@ -82,6 +83,7 @@ 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);
+            var clickId = form.Read("clickId", string.Empty);
             int accountid = form.Read("aid", 0);
             var commerceType = form.Read<int>("commerceType", 0);
 
@@ -89,7 +91,7 @@ namespace molilian.api.Controllers
             //ip = "127.0.0.1";
             //oaid = "test-oaid";
 #endif
-            return await UnionParseCore.UnionParseAsync(content, channel, commerceType, ip, oaid, accountid);
+            return await UnionParseCore.UnionParseAsync(content, channel, commerceType, ip, oaid, accountid, clickId);
         }
 
 
@@ -100,6 +102,7 @@ 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);
+            var clickId = form.Read("clickId", string.Empty);
             int accountid = form.Read("aid", 0);
             int count = form.Read("count", 0);
             var commerceType = form.Read<int>("commerceType", 0);
@@ -110,7 +113,7 @@ namespace molilian.api.Controllers
 #endif
             for (int i = 0; i < count; i++)
             {
-                _ = UnionParseCore.UnionParseAsync(content[i], channel, commerceType, ip, oaid, accountid);
+                _ = UnionParseCore.UnionParseAsync(content[i], channel, commerceType, ip, oaid, accountid, clickId);
             }
             return new APIResult(new { msg = "ok" });
         }
@@ -126,6 +129,7 @@ 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);
+            var clickId = form.Read("clickId", string.Empty);
 
             //验证签名
             if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
@@ -149,7 +153,7 @@ namespace molilian.api.Controllers
             {
                 return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
             }
-            return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, ip, oaid);
+            return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, ip, oaid, clickId);
         }
 
 
@@ -161,11 +165,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);
+            var clickId = form.Read("clickId", string.Empty);
 #if DEBUG
             ip = "127.0.0.1";
             oaid = "test-oaid";
 #endif
-            return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, ip, oaid);
+            return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, ip, oaid, clickId);
         }
 
         /// <summary>

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


+ 16 - 4
molilian.api/Properties/launchSettings.json

@@ -4,9 +4,21 @@
       "commandName": "Project",
       "launchBrowser": true,
       "launchUrl": "swagger",
-      "environmentVariables3": {
+      "environmentVariables": {
         "ASPNETCORE_ENVIRONMENT": "Development",
-        "EndPoint": "bj",
+        "EndPoint": "bj2",
+        "NtfyServer": "https://ntfy.yunhui800.com/5Sq9BytXXM5WDY3G",
+        "ANPush": "",
+        "DBType": "MySQL",
+        "DBConfig": "Server=rm-2ze74506m3gfsqe7mco.rwlb.rds.aliyuncs.com; Port=3306; Database=coupon; Uid=coupon; Pwd=67ktWBmw5G4yMs4J;SslMode=None;CharSet=utf8mb4;ConnectionTimeout=60;",
+        "RedisConfig": "101.200.46.46:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook",
+        "CenterDB": "",
+        "CenterRedis": ""
+      }
+    },
+      "environmentVariables2": {
+        "ASPNETCORE_ENVIRONMENT": "Development",
+        "EndPoint": "bj2",
         "NtfyServer": "https://ntfy.yunhui800.com/5Sq9BytXXM5WDY3G",
         "ANPush": "",
         "DBType": "MySQL",
@@ -15,7 +27,7 @@
         "CenterDB": "",
         "CenterRedis": ""
       },
-      "environmentVariables": {
+      "environmentVariables6": {
         "ASPNETCORE_ENVIRONMENT": "Development",
         "EndPoint": "bj5",
         "NtfyServer": "https://ntfy.yunhui800.com/5Sq9BytXXM5WDY3G",
@@ -26,7 +38,7 @@
         "CenterDB": "",
         "CenterRedis": ""
       },
-      "environmentVariables2": {
+      "environmentVariables1": {
         "ASPNETCORE_ENVIRONMENT": "Development",
         "EndPoint": "cadmin",
         "NtfyServer": "https://ntfy.yunhui800.com/5Sq9BytXXM5WDY3G",

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

@@ -11,7 +11,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'" />
 
   <ItemGroup>
-    <PackageReference Include="dodohold.core" Version="1.0.1.14" />
+    <PackageReference Include="dodohold.core" Version="1.0.1.17" />
     <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.0-Preview.1" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
     <PackageReference Include="YunhuiKit" Version="0.0.3" />

+ 4 - 3
molilian.core/Authorization/Provider/APIProvider.cs

@@ -58,18 +58,18 @@ namespace molilian.core
             return tokenCore.Delete(domain, ticket);
         }
 
-        public IAccessTokenDTO Create(long id, string key, string secret, string roles, string domain, string clientIp)
+        public IAccessTokenDTO Create(long id, string key, string secret, string roles, string state, string domain, string clientIp)
         {
             //TODO  暂时就一个客户端授权码,以后做成数据库的
             if (string.IsNullOrEmpty(key) || !key.Equals(_consumerKey)) { return null; }
             if (string.IsNullOrEmpty(secret) || !secret.Equals(_consumerSecret)) { return null; }
 
-            AccessTokenDTO token = Generate(id, key, domain, clientIp);
+            AccessTokenDTO token = Generate(id, key, state, domain, clientIp);
             tokenCore.Create(token);
             return token;
         }
 
-        public AccessTokenDTO Generate(long id, string accessKey, string domain, string clientIp)
+        public AccessTokenDTO Generate(long id, string accessKey, string state, string domain, string clientIp)
         {
             DateTime now = DateTime.Now;
             AccessTokenDTO token = new AccessTokenDTO
@@ -78,6 +78,7 @@ namespace molilian.core
                 AccessKey = accessKey,
                 create_time = now.Convert2UnixTimestamp(),
                 ExpiresIn = 0,
+                AccessState = state,
                 Domain = domain,
                 ClientIp = clientIp,
                 AccessTicket = $"{accessKey}|{domain}|{now}|{clientIp}".ToAES256()

+ 4 - 3
molilian.core/Authorization/Provider/AdminProvider.cs

@@ -105,9 +105,9 @@ namespace molilian.core
         /// <param name="domain"></param>
         /// <param name="clientIp"></param>
         /// <returns></returns>
-        public IAccessTokenDTO Create(long id, string key, string secret, string roles, string domain, string clientIp)
+        public IAccessTokenDTO Create(long id, string key, string secret, string roles, string state, string domain, string clientIp)
         {
-            AccessTokenDTO token = Generate(id, key, secret, roles, domain, clientIp);
+            AccessTokenDTO token = Generate(id, key, secret, roles, state, domain, clientIp);
             tokenCore.Create(token);
             return token;
         }
@@ -121,7 +121,7 @@ namespace molilian.core
         /// <param name="domain"></param>
         /// <param name="clientIp"></param>
         /// <returns></returns>
-        public AccessTokenDTO Generate(long id, string accessKey, string secret, string roles, string domain, string clientIp)
+        public AccessTokenDTO Generate(long id, string accessKey, string secret, string roles, string state, string domain, string clientIp)
         {
             DateTime now = DateTime.Now;
             AccessTokenDTO token = new AccessTokenDTO
@@ -131,6 +131,7 @@ namespace molilian.core
                 AccessRoles = roles,
                 create_time = now.Convert2UnixTimestamp(),
                 ExpiresIn = 0,
+                AccessState = state,
                 Domain = domain,
                 ClientIp = clientIp,
                 AccessTicket = $"{accessKey}|{secret}|{roles}|{domain}|{now}|{clientIp}".ToAES256()

+ 4 - 3
molilian.core/Authorization/Provider/UserProvider.cs

@@ -102,9 +102,9 @@ namespace molilian.core
         /// <param name="domain"></param>
         /// <param name="clientIp"></param>
         /// <returns></returns>
-        public IAccessTokenDTO Create(long id, string key, string secret, string roles, string domain, string clientIp)
+        public IAccessTokenDTO Create(long id, string key, string secret, string roles, string state, string domain, string clientIp)
         {
-            AccessTokenDTO token = Generate(id, key, secret, roles, this.Domain, clientIp);
+            AccessTokenDTO token = Generate(id, key, secret, roles, state, this.Domain, clientIp);
             tokenCore.Create(token);
             return token;
         }
@@ -118,7 +118,7 @@ namespace molilian.core
         /// <param name="domain"></param>
         /// <param name="clientIp"></param>
         /// <returns></returns>
-        public AccessTokenDTO Generate(long id, string accessKey, string secret, string accessRoles, string domain, string clientIp)
+        public AccessTokenDTO Generate(long id, string accessKey, string secret, string accessRoles, string state, string domain, string clientIp)
         {
             DateTime now = DateTime.Now;
             AccessTokenDTO token = new AccessTokenDTO
@@ -128,6 +128,7 @@ namespace molilian.core
                 AccessRoles = accessRoles,
                 create_time = now.Convert2UnixTimestamp(),
                 ExpiresIn = 0,
+                AccessState = state,
                 Domain = domain,
                 ClientIp = clientIp,
                 AccessTicket = $"{accessKey}|{secret}|{accessRoles}|{domain}|{now}|{clientIp}".ToAES256()

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

@@ -29,6 +29,29 @@ namespace molilian.core
 
         private static readonly object _lockObj = new();
         private static IEnumerable<ProxyNodesDTO> _cached;
+        public static string GetSelectOne(string node)
+        {
+            var list = List();
+            if (!list.Any()) return null;
+            if (!node.Contains(",")) return node;
+
+            // 处理包含逗号的节点参数
+            string selectedNode = node;
+            var nodes = node.Split(',', StringSplitOptions.RemoveEmptyEntries)
+                           .Select(n => n.Trim())
+                           .Where(n => !string.IsNullOrEmpty(n))
+                           .ToArray();
+
+            if (nodes.Length > 0)
+            {
+                // 随机选择一个节点
+                var random = new Random();
+                selectedNode = nodes[random.Next(nodes.Length)];
+            }
+            return selectedNode;
+        }
+
+
         public static WebProxy? GetOne(string node)
         {
             var list = List();
@@ -51,7 +74,6 @@ namespace molilian.core
                 }
             }
 
-
             var ProxyNodesDTO = list.Where(e => SelectEndPointUseProxy(e, selectedNode))
                                    .OrderBy(l => Guid.NewGuid())
                                    .FirstOrDefault();
@@ -67,6 +89,8 @@ namespace molilian.core
 
 
 
+
+
         public static WebProxy? GetOne(int nodeid)
         {
             var list = List();

+ 143 - 2
molilian.core/Core/aliyun/AliyunCore.cs

@@ -7,6 +7,9 @@ using AlibabaCloud.SDK.Vpc20160428.Models;
 using TencentCloud.Dbbrain.V20210527.Models;
 using Org.BouncyCastle.Bcpg.OpenPgp;
 using TencentCloud.Tke.V20180525.Models;
+using static AlibabaCloud.SDK.Ecs20140526.Models.DescribeInstancesResponseBody;
+using static AlibabaCloud.SDK.Ecs20140526.Models.DescribeNetworkInterfacesResponseBody;
+using static AlibabaCloud.SDK.Vpc20160428.Models.DescribeEipAddressesResponseBody.DescribeEipAddressesResponseBodyEipAddresses;
 
 namespace molilian.core
 {
@@ -14,7 +17,7 @@ namespace molilian.core
     public partial class AliyunCore
     {
         private AliyunPlus plus;
-        private AliyunAccountDTO _account;
+        public AliyunAccountDTO _account;
 
         public AliyunCore(int id)
         {
@@ -27,7 +30,42 @@ namespace molilian.core
         {
             return plus.QueryAccountBalance();
         }
-        //public bool ChangePublicIp(string region, string instanceId, string privateIp)
+
+        /// <summary>
+        /// 获取这个地区下的所有ecs
+        /// </summary>
+        /// <param name="region"></param>
+        /// <returns></returns>
+        /// <exception cref="Exception"></exception>
+        public DescribeInstancesResponseBodyInstances GetInstances(string region)
+        {
+            try
+            {
+                //查询实例信息
+                var response = plus.DescribeInstances(region);
+                var Instances = response.Body.Instances;
+                return Instances;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
+        }
+        public DescribeNetworkInterfacesResponseBodyNetworkInterfaceSets GetNetworkInterfaces(string region)
+        {
+            try
+            {
+                //查询实例信息
+                var response = plus.DescribeNetworkInterfaces(region);
+                var networkInterfaces = response.Body.NetworkInterfaceSets;
+                return networkInterfaces;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
+        }
+        //public bool xxx(string region, string instanceId, string privateIp)
         //{
         //    try
         //    {
@@ -36,6 +74,7 @@ namespace molilian.core
         //        var vswitchId = instance.Body.VpcAttributes.VSwitchId;
         //        var securityGroupId = instance.Body.SecurityGroupIds.SecurityGroupId;
 
+        //        plus.DescribeNetworkInterfaces(region, instanceId)
         //        //释放弹性网卡
         //        ReleaseEipAddress("cn-beijing", allocationId);
         //        //申请并绑定公网IP
@@ -48,6 +87,79 @@ namespace molilian.core
         //    }
         //}
 
+
+
+        public (bool, string, string) ChangePublicIp(string privateIp)
+        {
+            try
+            {
+                var regions = _account.regions?.Split(',');
+                foreach (var s in regions)
+                {
+                    var region = s.Trim();
+                    if (string.IsNullOrEmpty(region)) continue;
+
+                    //获取这个地区下的所有网卡
+                    var list = GetNetworkInterfaces(region);
+                    if (list == null) continue;
+
+                    foreach (var networkInterface in list.NetworkInterfaceSet)
+                    {
+                        //找出网卡信息
+                        string networkInterfaceId = networkInterface.NetworkInterfaceId;
+                        var privateIps = networkInterface?.PrivateIpSets;
+
+                        var taraget = privateIps?.PrivateIpSet.Where(e => e.PrivateIpAddress.Equals(privateIp)).FirstOrDefault();
+                        if (taraget == null) break;
+
+                        //找到当前公网IP
+                        string currentPublicIp = taraget?.AssociatedPublicIp?.PublicIpAddress;
+                        if (string.IsNullOrEmpty(currentPublicIp)) throw new Exception("没有找到公网IP");
+
+                        //第1步、获取当前的公网EIP
+                        var currentEip = DescribeEipAddresse(region, currentPublicIp) ?? throw new Exception("没有找到 EIP");
+                        var currentAllocationId = currentEip.AllocationId;
+
+                        //第2步、申请新的公网ip
+                        var eip = plus.AllocateEipAddress(region);
+                        var allocationId = eip.Body.AllocationId;
+                        string eipAddress = eip.Body.EipAddress;
+
+                        //第3步、解绑当前的公网ip
+                        plus.UnassociateEipAddress(region, currentAllocationId);
+
+                        //第4步、检查公网ip是否成功解绑
+                        string unPublicIpAddress = currentPublicIp;
+                        while (!string.IsNullOrEmpty(unPublicIpAddress))
+                        {
+                            var networkInterfaceState = plus.DescribeNetworkInterfaceAttribute(region, networkInterfaceId);
+                            var currentPrivateIpSet = networkInterfaceState?.Body?.PrivateIpSets?.PrivateIpSet;
+
+                            var currentPrivateIpAddress = currentPrivateIpSet.Where(e => e.PrivateIpAddress.Equals(privateIp)).FirstOrDefault();
+                            unPublicIpAddress = currentPrivateIpAddress?.AssociatedPublicIp?.PublicIpAddress;
+                            if (string.IsNullOrEmpty(unPublicIpAddress)) break;
+                            Thread.Sleep(500);
+                        }
+
+                        //第5步、绑定新的公网ip
+                        var AssociateEipAddress =
+                            plus.AssociateEipAddress(region, allocationId, networkInterfaceId, EIPInstanceType.NetworkInterface, privateIp);
+
+                        //第5步、释放当前的公网IP
+                        plus.ReleaseEipAddress(region, currentAllocationId);
+
+                        return (true, currentPublicIp, eipAddress);
+                    }
+                }
+                throw new Exception("没有符合的数据");
+
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
+        }
+
         public bool EcsCreateNetworkInterface(string region, string instanceId)
         {
             try
@@ -165,6 +277,35 @@ namespace molilian.core
                 throw new Exception(ex.Message);
             }
         }
+
+        public List<DescribeEipAddressesResponseBodyEipAddressesEipAddress> DescribeEipAddresses(string region, string eipAddress)
+        {
+            try
+            {
+                var response = plus.DescribeEipAddresses(region, eipAddress);
+                var list = response?.Body?.EipAddresses?.EipAddress;
+                return list;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
+        }
+
+        public DescribeEipAddressesResponseBodyEipAddressesEipAddress DescribeEipAddresse(string region, string eipAddress)
+        {
+            try
+            {
+                var response = plus.DescribeEipAddresses(region, eipAddress);
+                var eip = response?.Body?.EipAddresses?.EipAddress?.FirstOrDefault();
+                return eip;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
+        }
+
         public bool ReleaseEipAddress(string region, string allocationId)
         {
             try

+ 2 - 2
molilian.core/Core/dataoke/DataokeCore.cs

@@ -110,7 +110,7 @@ namespace molilian.core
                 result.accountName = string.Empty;
                 result.content = content;
                 result.shortLinkurl = url;
-                result.deeplink_url = JdUnionPlus.GetDeeplink(null);
+                result.deeplink_url = JdUnionPlus.GetDeeplink(null, string.Empty);
             }
             else
             {
@@ -142,7 +142,7 @@ namespace molilian.core
 
                 GoodsDetailDTO goods = null;
                 if (success) goods = plus.GetGoods(shortLinkurl);
-                result.deeplink_url = JdUnionPlus.GetDeeplink(shortLinkurl);
+                result.deeplink_url = JdUnionPlus.GetDeeplink(shortLinkurl, string.Empty);
 
                 if (goods != null)
                 {

+ 1 - 2
molilian.core/Core/jd/JdPoolCore.cs

@@ -255,7 +255,7 @@ namespace molilian.core
                 tags = ["red_circle"]
             });
 
-            NotifyCore.AnPushNotify("掉线", $"【京东{accountId}:{name}】cookie 掉线");
+            //NotifyCore.AnPushNotify("掉线", $"【京东{accountId}:{name}】cookie 掉线");
             EndPointCore.NotifyReload(true);
         }
 
@@ -276,7 +276,6 @@ namespace molilian.core
             });
             NotifyCore.AnPushNotify("没账号", $"【京东联盟】没有匹配账号");
         }
-
     }
 
 

+ 1 - 1
molilian.core/Core/ks/KsPoolCore.cs

@@ -217,7 +217,7 @@ namespace molilian.core
                 tags = ["red_circle"]
             });
 
-            NotifyCore.AnPushNotify("掉线", $"【快手{accountId}:{name}】cookie 掉线");
+            //NotifyCore.AnPushNotify("掉线", $"【快手{accountId}:{name}】cookie 掉线");
             EndPointCore.NotifyReload(true);
         }
 

+ 4 - 4
molilian.core/Core/log/base.cs

@@ -73,7 +73,7 @@ namespace molilian.core
                                 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";
+                                node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
                                 break;
                             default: return 0;
                         }
@@ -441,7 +441,7 @@ namespace molilian.core
                         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";
+                        node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
                         break;
                     default: return Task.CompletedTask;
                 }
@@ -644,7 +644,7 @@ namespace molilian.core
                         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";
+                        node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
                         break;
                     default: return 0;
                 }
@@ -687,7 +687,7 @@ namespace molilian.core
                         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";
+                        node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
                         break;
                     default: return [];
                 }

+ 35 - 1
molilian.core/Core/log/jd.cs

@@ -71,7 +71,7 @@ namespace molilian.core
             {
                 var ts = DateTime.Now - response.create_time;
                 response.elapsedTime = (int)ts.TotalMilliseconds;
-                _ = RedisHelper.RPushAsync(failure_key, response);
+                _ = RedisHelper.RPushAsync(queue_parse_jd_key, response);
 
                 if (!response.ip.Contains("127.0.0"))
                 {
@@ -115,6 +115,40 @@ namespace molilian.core
                 {
                     JdPoolCore.AccountExhausted();
                 }
+
+                string failure_key = ":total:continuous_failure";
+                string failure_lock_key = ":lock:continuous_failure";
+                if (response.success) RedisHelper.Del(failure_key);
+
+                //连续错误发送报警
+                if ("签名失败".Equals(response.reason) || "网络异常".Equals(response.reason))
+                {
+                    var total = RedisHelper.IncrBy(failure_key);
+                    RedisHelper.Expire(failure_key, 3600);
+
+                    if (total > 30)
+                    {
+                        //没有锁定记录才发送,
+                        string lockfFlag = RedisHelper.Get(failure_lock_key);
+                        if (string.IsNullOrEmpty(lockfFlag))
+                        {
+                            //发送锁,保存半小时(半小时内只发送1次)
+                            RedisHelper.Set(failure_lock_key, 1, 1800);
+
+                            string message = $"【京东{response.accountName}】{EndPointCore.CurrentEndPoint},连续的{response.reason}";
+                            RedisHelper.Expire(failure_key, 3600);
+                            NotifyCore.Notify(new NifyMessage
+                            {
+                                message = message,
+                                priority = NifyMessagePriority.high,
+                                tags = ["red_circle"]
+                            });
+                            NotifyCore.AnPushNotify(response.reason, message);
+                        }
+                    }
+
+                }
+
             }
             catch (Exception ex) { }
         }

+ 1 - 0
molilian.core/Core/log/promotion.cs

@@ -59,6 +59,7 @@ namespace molilian.core
                     .Add("accountId", data.accountId)
                     .Add("accountName", data.accountName)
                     .Add("proxy_node", data.proxy_node)
+                    .Add("proxy_nodename", data.proxy_nodename)
                     .Add("img", data.img)
                     .Add("ip", data.ip)
                     .Add("oaid", data.oaid)

+ 1 - 0
molilian.core/Core/log/taobao.cs

@@ -153,6 +153,7 @@ namespace molilian.core
                 .Add("message", data.message)
                 .Add("reason", data.reason)
                 .Add("content", data.content)
+                .Add("mktId", data.mktId)
                 .Add("itemId", data.itemId)
                 .Add("itemName", data.itemName)
                 .Add("pic", data.pic)

+ 1 - 1
molilian.core/Core/pdd/PddPoolCore.cs

@@ -155,7 +155,7 @@ namespace molilian.core
                 tags = ["red_circle"]
             });
 
-            NotifyCore.AnPushNotify("掉线", $"【多多{accountId}:{name}】cookie 掉线");
+            //NotifyCore.AnPushNotify("掉线", $"【多多{accountId}:{name}】cookie 掉线");
             EndPointCore.NotifyReload(true);
         }
 

+ 33 - 5
molilian.core/Core/taoke/OrderTrackingCore.cs

@@ -45,18 +45,37 @@ namespace molilian.core
             string cacheKey = $":cache:order_summary:{item.accountId}:{item.itemId}";
             RedisHelper.Set(cacheKey, newData, ttl);
 
+            string mktId = item.mktId;
+            if (!string.IsNullOrEmpty(mktId) && mktId.Contains('-'))
+            {
+                mktId = mktId.Split('-')[^1];
+                cacheKey = $":cache:order_summary:{item.accountId}:mktId:{mktId}";
+                RedisHelper.Set(cacheKey, newData, ttl);
+            }
+
             cacheKey = $":cache:order_summary:{item.accountId}:{item.itemName}";
             RedisHelper.Set(cacheKey, newData, ttl);
         }
 
-        public static TkDataDTO GetLinkSummary(int accountId, string itemId, string itemTitle)
+        public static TkDataDTO GetLinkSummary(int accountId, string itemId, string mktId, string itemTitle)
         {
+            if (!string.IsNullOrEmpty(mktId) && mktId.Contains('-'))
+            {
+                mktId = mktId.Split('-')[^1];
+            }
             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(mktId))
+                {
+                    string cacheKey = $":cache:order_summary:{accountId}:mktId:{mktId}";
+                    var result = redis.Get<TkDataDTO>(cacheKey);
+                    if (result != null) return result;
+                }
+
                 if (!string.IsNullOrEmpty(itemId))
                 {
                     string cacheKey = $":cache:order_summary:{accountId}:{itemId}";
@@ -74,9 +93,8 @@ namespace molilian.core
             return result.Count > 0 ? result[0] : null;
         }
 
-        public static async void RemoveLinkSummary(int accountId, string itemId)
+        public static async void RemoveLinkSummary(int accountId, string itemId, string mktId, string itemTitle)
         {
-            string cacheKey = $":cache:order_summary:{accountId}:{itemId}";
             await EndPointCore.ProcessEndPointNodesAsync(node =>
             {
                 if (!node.is_public_api) return Task.CompletedTask;
@@ -84,7 +102,16 @@ namespace molilian.core
 
 
                 var redis = RedisClientManager.GetRedisClient(node.redis_server);
+
+                string cacheKey = $":cache:order_summary:{accountId}:{itemId}";
+                redis.Del(cacheKey);
+
+                cacheKey = $":cache:order_summary:{accountId}:mktId:{mktId}";
+                redis.Del(cacheKey);
+
+                cacheKey = $":cache:order_summary:{accountId}:{itemTitle}";
                 redis.Del(cacheKey);
+
                 return Task.CompletedTask;
             });
         }
@@ -93,7 +120,7 @@ namespace molilian.core
         {
             if (item.tbPaidTime < DateTime.Now.AddDays(-1)) return false;
 
-            var summary = GetLinkSummary(item.accountId, item.itemId, item.itemTitle);
+            var summary = GetLinkSummary(item.accountId, item.itemId, item.mktId, item.itemTitle);
             if (summary == null) return false;
 
 
@@ -134,6 +161,7 @@ namespace molilian.core
                 batchId = batchId,
                 ip = summary.ip,
                 oaid = summary.oaid,
+                mktId = summary.mktId,
                 itemId = summary.itemId,
                 itemName = summary.itemName,
                 taoToken = summary.taoToken,
@@ -152,7 +180,7 @@ namespace molilian.core
             };
 
             conn.Replace(data);
-            RemoveLinkSummary(item.accountId, item.itemTitle);
+            RemoveLinkSummary(item.accountId, item.itemId, item.mktId, item.itemTitle);
             return true;
         }
     }

+ 1 - 1
molilian.core/Core/taoke/RiskControlCore.cs

@@ -81,7 +81,7 @@ namespace molilian.core
                         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";
+                        node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
                         break;
                     default: return 0;
                 }

+ 35 - 1
molilian.core/Core/taoke/TaokeOpenCore.cs

@@ -1,7 +1,9 @@
 using dodohold.core;
+using Google.Protobuf.WellKnownTypes;
 using System.Text.Json;
 using System.Threading;
 using Top.Api.Response;
+using static dodohold.core.ZTOExpress.CreateOrderArgs;
 
 
 namespace molilian.core
@@ -94,16 +96,48 @@ namespace molilian.core
                     });
                 }
 
-                var proxy = ProxyNodesCore.GetOne(account.nodeName);
+                string nodeName = ProxyNodesCore.GetSelectOne(account.nodeName);
+                var proxy = ProxyNodesCore.GetOne(nodeName);
                 TaobaoOpenPlus taobao = new(account.appkey, account.appSecret, account.open_pid, debug, proxy);
                 int timeout = _config.similar_timeout;
 #if DEBUG
                 timeout = 50000;
 #endif
+                result.proxy_nodename = nodeName;
+                result.proxy_node = proxy?.Address?.Host;
+
                 using var cts = new CancellationTokenSource();
                 cts.CancelAfter(timeout);
 
                 DateTime stime = DateTime.Now;
+                if ("veapi".Equals(account.api) && account.api_id > 0)
+                {
+                    result.proxy_nodename = null;
+                    result.proxy_node = null;
+
+                    var api = VeapiPoolCore.Get(account.api_id);
+                    if (account != null)
+                    {
+                        var core = new VeapiPlus(account.name, api.key, api.sessionKey);
+                        core.picSimilaritem(img, ref result);
+
+                        var ts2 = DateTime.Now - stime;
+                        result.elapsedTime2 = (int)ts2.TotalMilliseconds;
+
+                        _ = TkLogCore.PromotionImgLogAsync(result);
+                        return new APIResult(new
+                        {
+                            result.success,
+                            result.message,
+                            result.reason,
+                            promotionImg = result.PromotionImg
+                        }, APIResultCodeEnum.OK, new JsonSerializerOptions
+                        {
+                            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+                        });
+                    }
+                }
+
 
                 var apiDelayTask = Task.Delay(500, cts.Token);
                 var apiRequestTask = Task.Run(() =>

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

@@ -12,14 +12,14 @@ namespace molilian.core
             _end_point = Environment.GetEnvironmentVariable("EndPoint");
         }
 
-        public static async Task<ActionResult> UnionCouponAsync(string content, string dplink, string channel, string ip, string oaid)
+        public static async Task<ActionResult> UnionCouponAsync(string content, string dplink, string channel, string ip, string oaid, string clickId)
         {
             switch (channel)
             {
                 case "tb":
                     return await TaobaoCouponAsync(content, dplink, ip, oaid);
                 case "jd":
-                    return await JdCouponAsync(content, dplink, ip, oaid);
+                    return await JdCouponAsync(content, dplink, ip, oaid, clickId);
                 default:
                     if (!string.IsNullOrEmpty(content.Trim()))
                     {
@@ -177,7 +177,7 @@ namespace molilian.core
             });
         }
 
-        public static async Task<APIResult> JdCouponAsync(string content, string dplink, string ip, string oaid)
+        public static async Task<APIResult> JdCouponAsync(string content, string dplink, string ip, string oaid, string clickId)
         {
             content = content.UrlDecode();
             dplink = dplink.UrlDecode();
@@ -258,7 +258,7 @@ namespace molilian.core
                         channel = result.channel.ToString(),
                     });
                 }
-                result = await JdUnionPlus.JdCouponAsync(account, api, content, result);
+                result = await JdUnionPlus.JdCouponAsync(account, api, content, clickId, result);
                 if (result.success && result.couponAmount == 0)
                 {
                     result.success = false;

+ 16 - 15
molilian.core/Core/taoke/UnionParseCore.cs

@@ -32,7 +32,7 @@ namespace molilian.core
 {
     public partial class UnionParseCore
     {
-        public static async Task<ActionResult> UnionParseAsync(string content, string channel, int commerceType, string ip, string oaid, int accountid = 0)
+        public static async Task<ActionResult> UnionParseAsync(string content, string channel, int commerceType, string ip, string oaid, int accountid = 0, string clickId = "")
         {
 
             content = content.Trim();
@@ -40,7 +40,7 @@ namespace molilian.core
             {
                 "wemeet" => await WemeetParseAsync(content, ip, oaid),
                 "bdpan" => PanParse(content, ip, oaid),
-                "jd" => await JdParseAsync(content, commerceType, ip, oaid, accountid),
+                "jd" => await JdParseAsync(content, commerceType, ip, oaid, accountid, clickId),
                 "ks" => await KsParseAsync(content, commerceType, ip, oaid, accountid),
                 "dy" => await DyParseAsync(content, commerceType, ip, oaid),
                 "pdd" => await PddParseAsync(content, commerceType, ip, oaid, accountid),
@@ -501,16 +501,18 @@ namespace molilian.core
         }
 
         public static async Task<APIResult> JdParseAsync(string content, int commerceType, string ip, string oaid,
-            int accountid = 0, CancellationToken cancellationToken = default)
+            int accountid = 0, string clickId = "", CancellationToken cancellationToken = default)
         {
-            var result = JdUnionPlus.GetFormattedObject(content, ip, oaid);
+
+            var config = TkConfigCore.Get();
+         
+
+            var result = JdUnionPlus.GetFormattedObject(   content, ip, oaid, clickId);
             content = content.UrlDecode();
             result.rawContent = content;
             bool IfExceptional = false;
             try
             {
-                var config = TkConfigCore.Get();
-
 
                 if (!string.IsNullOrEmpty(config.jd_blacklist_regular))
                 {
@@ -531,8 +533,7 @@ namespace molilian.core
                         _ = TkLogCore.ParseLogAsync(result);
                         return JdParseOutput(result);
                     }
-                }
-
+                } 
 
                 //============================== 放弃转链-地区过滤 ==============================
                 if (!result.ip.StartsWith("127.0.0") && accountid == 0 && JdUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
@@ -545,8 +546,8 @@ namespace molilian.core
                         LinkTypeEnum.live or
                         LinkTypeEnum.video or
                         LinkTypeEnum.profile or
-                        LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
-                        _ => JdUnionPlus.GetDeeplink(string.Empty),
+                        LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl, clickId),
+                        _ => JdUnionPlus.GetDeeplink(string.Empty, clickId),
                     };
 
                     //if (result.link_type == LinkTypeEnum.other_aff)
@@ -593,8 +594,8 @@ namespace molilian.core
                     result.reason = "没有匹配账号";
                     result.deeplink_url = result.link_type switch
                     {
-                        LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
-                        _ => JdUnionPlus.GetDeeplink(string.Empty),
+                        LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl, clickId),
+                        _ => JdUnionPlus.GetDeeplink(string.Empty, clickId),
                     };
 
                     _ = TkLogCore.ParseLogAsync(result);
@@ -605,7 +606,7 @@ namespace molilian.core
 
                 var plus = new JdUnionPlus(account);
 
-                result = await plus.JdParseAsync(content, commerceType, result, cancellationToken);
+                result = await plus.JdParseAsync(content, commerceType, clickId, result, cancellationToken);
             }
             catch (Exception ex)
             {
@@ -635,8 +636,8 @@ namespace molilian.core
                 }
                 result.deeplink_url = result.link_type switch
                 {
-                    LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
-                    _ => JdUnionPlus.GetDeeplink(string.Empty),
+                    LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl, clickId),
+                    _ => JdUnionPlus.GetDeeplink(string.Empty, clickId),
                 };
             }
             _ = TkLogCore.ParseLogAsync(result);

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

@@ -11,6 +11,7 @@ namespace molilian.core
         public int accountId { get; set; } = 0;
         public string accountName { get; set; } = string.Empty;
         public string proxy_node { get; set; } = string.Empty;
+        public string proxy_nodename { get; set; } = string.Empty;
         public string img { get; set; } = string.Empty;
         public string ip { get; set; } = string.Empty;
         public string oaid { get; set; } = string.Empty;

+ 3 - 0
molilian.core/DTO/alimama/TkConfigDTO.cs

@@ -33,6 +33,9 @@ namespace molilian.core
         public string jd_blacklist_regular { get; set; } = string.Empty;
         public string jd_h5st_sign_url { get; set; } = string.Empty;
         public string jd_h5st_sign_version { get; set; } = string.Empty;
+        public string dp_style { get; set; } = string.Empty;
+        public int dp_style_percentage { get; set; } = 0;
+        public string dp_style_default_str { get; set; } = string.Empty;
 
         public int tk_limit_per_ip_24h { get; set; } = 0;
         public int tk_limit_per_oaid_24h { get; set; } = 0;

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

@@ -99,6 +99,7 @@ namespace molilian.core
         public string num_iid { get; set; } = string.Empty;
 
 
+        public string mktId { get; set; } = string.Empty;
         public string itemId { get; set; } = string.Empty;
         public string itemName { get; set; } = string.Empty;
         public decimal couponAmount { get; set; } = 0;

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

@@ -16,6 +16,7 @@ namespace molilian.core
         public string batchId { get; set; } = string.Empty;
         public string ip { get; set; } = string.Empty;
         public string oaid { get; set; } = string.Empty;
+        public string mktId { get; set; } = string.Empty;
         public string itemId { get; set; } = string.Empty;
         public string itemName { get; set; } = string.Empty;
         public string taoToken { get; set; } = string.Empty;

+ 32 - 12
molilian.core/Plus/Alimama/orders.cs

@@ -519,9 +519,9 @@ SET  order_ord_num = order_ord_num_3 + order_ord_num_12 + order_ord_num_13 + ord
                 }
                 catch (Exception ex)
                 {
-                        _ = new LoggerLibrary("debug", "GetTkOrders")
-                            .Info(body)
-                            .SaveAsync();
+                    _ = new LoggerLibrary("debug", "GetTkOrders")
+                        .Info(body)
+                        .SaveAsync();
                     string message = $"【GetRawItemId】{_accountId}:{_accountName}\t{_proxy?.Address}\n" +
                         $"{body}\n{ex.Message}\n{ex.StackTrace}";
 
@@ -550,7 +550,7 @@ SET  order_ord_num = order_ord_num_3 + order_ord_num_12 + order_ord_num_13 + ord
                         }
 
                         //进行订单和转链匹配
-                        item.itemId = GetRawItemId(item.mktId);
+                        //(int state, item.itemId) = GetRawItemId(item.mktId);
                         if (item.tkStatus == 3 && item.tbPaidTime != DateTime.MinValue) orderTimes.Add(item.tbPaidTime.Date);
                         int? id = conn.Replace(item);
                         if (id != null)
@@ -580,19 +580,19 @@ SET  order_ord_num = order_ord_num_3 + order_ord_num_12 + order_ord_num_13 + ord
         }
 
 
-        string GetRawItemId(string mktId)
+        public (int, string) GetRawItemId(string mktId)
         {
             string body = string.Empty, location = string.Empty;
             try
             {
                 string lock_key = $"lock:GetRawItemId:disabled";
                 int count = RedisHelper.Get<int>(lock_key);
-                if (count > 0) return null;
+                if (count > 0) return (0, null);
 
                 string cacheKey = $":cache:mkt2itemId:{mktId}";
 
                 string itemId = RedisHelper.Get(cacheKey);
-                if (itemId != null) return itemId;
+                if (itemId != null) return (1, itemId);
 
 
                 var ts = DateTime.Now.Convert2UnixTimestamp(true);
@@ -624,12 +624,13 @@ SET  order_ord_num = order_ord_num_3 + order_ord_num_12 + order_ord_num_13 + ord
                 }
 
                 location = response.ResponseMessage?.Headers?.Location?.ToString();
+                string message;
                 if (!string.IsNullOrEmpty(location) && location.Contains("err.taobao.com/error1.html"))
                 {
                     RedisHelper.Set(lock_key, 1, 60);
 
-                    string message = $"【GetRawItemId】{_accountId}:{_accountName}\t{_proxy?.Address}\n" +
-                        $"{mktId}\n{location}";
+                    message = $"【GetRawItemId】{_accountId}:{_accountName}\t{_proxy?.Address}\n" +
+                       $"{mktId}\n{location}";
 
                     //NotifyCore.Notify(new NifyMessage
                     //{
@@ -637,17 +638,36 @@ SET  order_ord_num = order_ord_num_3 + order_ord_num_12 + order_ord_num_13 + ord
                     //    priority = NifyMessagePriority.high,
                     //    tags = ["red_circle"]
                     //});
-                    return null;
+                    return (0, null);
                 }
 
                 body = response.Body();
                 var root = body.Convert2JsonElement();
+
+                int code = root.PathRead<int>("code");
+                message = root.PathRead<string>("info.message");
+
+                //if ("nologin".Equals(message))
+                //{
+                //    (bool success, message) = RenewCookie();
+                //    if (!success)
+                //    {
+                //        TkPoolCore.Disabled(_accountId, _accountName, body);
+                //        throw new Exception("nologin");
+                //    }
+                //    return (-1, null);
+                //}
+
                 itemId = root.PathRead<string>("model.item.itemId");
                 if (!string.IsNullOrEmpty(itemId))
                 {
                     RedisHelper.Set(cacheKey, itemId, 86400 * 7);
                 }
-                return itemId;
+                else
+                {
+                    //RedisHelper.Set(lock_key, 1, 3600);
+                }
+                return (1, itemId);
             }
             catch (Exception ex)
             {
@@ -661,7 +681,7 @@ SET  order_ord_num = order_ord_num_3 + order_ord_num_12 + order_ord_num_13 + ord
                     tags = ["red_circle"]
                 });
             }
-            return null;
+            return (0, null);
         }
 
 

+ 3 - 3
molilian.core/Plus/Alimama/parse.cs

@@ -246,7 +246,7 @@ namespace molilian.core
             string result = string.Empty;
             if (matches.Count > 0)
             {
-                result = matches[^1].Value; // 返回第一个匹配到的 URL
+                 result = Regex.Replace(matches[^1].Value, @"\++$", "");
             }
             result = result.Replace("&nbsp;", "");
 
@@ -258,14 +258,14 @@ namespace molilian.core
         public static string GetTaobaoLink(string content)
         {
             if (string.IsNullOrEmpty(content)) return content;
-            string result = content;
             string pattern = @"(https?://(?:[\w-]+\.)*(?:tb\.cn|taobao\.com|juhuasuan\.com|tmall\.com|tmall\.hk)(?:/[a-zA-Z0-9\-\._~:/?#[\]@!$&'()*+,;=%]*)?)";
             Regex regex = new(pattern, RegexOptions.IgnoreCase);
             MatchCollection matches = regex.Matches(content);
 
             if (matches.Count > 0)
             {
-                return matches[^1].Value; // 返回第一个匹配到的 URL
+                string result = Regex.Replace(matches[^1].Value, @"\++$", "");
+                return result;
             }
             return string.Empty;
         }

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

@@ -95,7 +95,7 @@ namespace molilian.core
             {
                 //第一种提取方法
                 string itemId = url.GetContentPart(".com/i", ".htm");
-                if (!string.IsNullOrEmpty(itemId) && int.TryParse(itemId, out int _))
+                if (!string.IsNullOrEmpty(itemId) && long.TryParse(itemId, out long _))
                 {
                     string resultUrl = $"https://item.taobao.com/item.htm?id={itemId}";
                     return (true, resultUrl);
@@ -728,6 +728,7 @@ namespace molilian.core
                 string couponEffectiveStartTime = root.PathRead("data.couponEffectiveStartTime", string.Empty);
 
                 string itemId = root.PathRead("data.itemId", string.Empty);
+                string mktId = root.PathRead("data.outputMktId", string.Empty);
                 string itemName = root.PathRead("data.itemName", string.Empty);
                 decimal promotionPrice = root.PathRead<decimal>("data.promotionPrice", 0);
                 string sellerNickName = root.PathRead("data.sellerNickName", string.Empty);
@@ -832,6 +833,7 @@ namespace molilian.core
                 result.taoToken = taoToken;
                 result.shortLinkurl = shortLinkurl;
                 result.deeplink_url = deeplink_url;
+                result.mktId = mktId;
 
                 result.itemId = itemId;
                 result.itemName = itemName;

+ 49 - 2
molilian.core/Plus/Aliyun/Vpc.cs

@@ -1,9 +1,56 @@
-using Tea;
+using AlibabaCloud.SDK.Vpc20160428.Models;
+using Tea;
 
 namespace molilian.core
 {
     public partial class AliyunPlus
     {
+        public DescribeEipAddressesResponse DescribeEipAddresses(string region, string eipAddress)
+        {
+            AlibabaCloud.OpenApiClient.Models.Config config = new()
+            {
+                AccessKeyId = _app_key,
+                AccessKeySecret = _app_secret,
+                Endpoint = $"vpc.{region}.aliyuncs.com"
+            };
+            AlibabaCloud.SDK.Vpc20160428.Client client = new(config);
+            AlibabaCloud.SDK.Vpc20160428.Models.DescribeEipAddressesRequest describeEipAddressesRequest = new AlibabaCloud.SDK.Vpc20160428.Models.DescribeEipAddressesRequest
+            {
+                RegionId = region,
+                EipAddress = eipAddress
+            };
+
+            AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
+            try
+            {
+                // 复制代码运行请自行打印 API 的返回值
+                var response = client.DescribeEipAddressesWithOptions(describeEipAddressesRequest, runtime);
+                return response;
+            }
+            catch (TeaException error)
+            {
+                // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
+                // 错误 message
+                Console.WriteLine(error.Message);
+                // 诊断地址
+                Console.WriteLine(error.Data["Recommend"]);
+                AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
+            }
+            catch (Exception _error)
+            {
+                TeaException error = new TeaException(new Dictionary<string, object>
+                {
+                    { "message", _error.Message }
+                });
+                // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
+                // 错误 message
+                Console.WriteLine(error.Message);
+                // 诊断地址
+                Console.WriteLine(error.Data["Recommend"]);
+                AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
+            }
+            return null;
+        }
 
         /// <summary>
         /// 申请弹性公网IP
@@ -139,7 +186,7 @@ namespace molilian.core
         /// <param name="allocationId"></param>
         /// <param name="region"></param>
         /// <returns></returns>
-        public AlibabaCloud.SDK.Vpc20160428.Models.UnassociateEipAddressResponse UnassociateEipAddress(string allocationId, string region = "cn-beijing")
+        public AlibabaCloud.SDK.Vpc20160428.Models.UnassociateEipAddressResponse UnassociateEipAddress(string region, string allocationId)
         {
             AlibabaCloud.OpenApiClient.Models.Config config = new()
             {

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

@@ -35,7 +35,7 @@ namespace molilian.core
 
                 WebClientUtility client = new WebClientUtility();
                 client.SetContentType("application/json");
-                client.Timeout = TimeSpan.FromMicroseconds(2000);
+                client.Timeout = TimeSpan.FromMilliseconds(2000);
                 client.Post(data);
                 var response = await client.RequestAsync(url, "POST", cancellationToken);
 

+ 42 - 14
molilian.core/Plus/JDUnion/JdUnionPlus.cs

@@ -60,7 +60,31 @@ namespace molilian.core
             return string.Empty;
         }
 
-        public static string GetDeeplink(string url)
+        public static string GetDeeplink(string url, string clickId)
+        {
+            var config = TkConfigCore.Get();
+            if (string.IsNullOrEmpty(config.dp_style)) return GetDefaultStyleDeeplink(url);
+
+            Random rand = new();
+            int randomValue = rand.Next(0, 101);
+            if (randomValue > config.dp_style_percentage) return GetDefaultStyleDeeplink(url);
+
+            if (string.IsNullOrEmpty(clickId)) clickId = config.dp_style_default_str;
+
+            var ts = DateTime.Now.Convert2UnixTimestamp(true);
+
+            string virtual_params = $"{{\"category\":\"jump\",\"des\":\"HomePage\",\"m_param\":{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}";
+            if (!string.IsNullOrEmpty(url))
+            {
+                virtual_params = $"{{\"category\":\"jump\",\"des\":\"m\",\"url\":\"{url}\",\"m_param\":{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}}}";
+            }
+
+            string result = $"openapp.jdmobile://virtual?params={virtual_params.UrlEncode()}";
+            return result;
+        }
+
+
+        public static string GetDefaultStyleDeeplink(string url)
         {
             if (string.IsNullOrEmpty(url)) return "openapp.jdmobile://";
             string virtual_params = $"{{\"category\":\"jump\",\"des\":\"m\",\"sourceValue\":\"babel-act\",\"sourceType\":\"babel\",\"url\":\"{url}\",\"M_sourceFrom\":\"h5auto\",\"msf_type\":\"auto\"}}";
@@ -68,10 +92,11 @@ namespace molilian.core
             return result;
         }
 
-        public static JdDataDTO GetFormattedObject(string content, string ip = "", string oaid = "")
+        public static JdDataDTO GetFormattedObject(string content, string ip = "", string oaid = "", string clickId = "")
         {
             string shortLinkurl = GetLink(content);
-            string deeplink_url = GetDeeplink(shortLinkurl);
+            string deeplink_url = GetDeeplink(shortLinkurl, clickId);
+
             return new JdDataDTO()
             {
                 message = string.Empty,
@@ -110,6 +135,9 @@ namespace molilian.core
                     Referer = "http://www.jd.com",
                     Proxy = ProxyNodesCore.RandomOne()
                 };
+#if DEBUG
+                client.Proxy = null;
+#endif
                 var response = client.Request(url);
                 if (!response.Successed) return null;
 
@@ -223,7 +251,7 @@ namespace molilian.core
         //    return result;
         //}
 
-        public async Task<JdDataDTO> JdParseAsync(string content, int commerceType, JdDataDTO result, CancellationToken cancellationToken = default)
+        public async Task<JdDataDTO> JdParseAsync(string content, int commerceType, string clickId, JdDataDTO result, CancellationToken cancellationToken = default)
         {
 
             string message = "OK";
@@ -239,7 +267,7 @@ namespace molilian.core
                 result.accountName = string.Empty;
                 result.content = content;
                 result.shortLinkurl = url;
-                result.deeplink_url = GetDeeplink(url);
+                result.deeplink_url = GetDeeplink(url, clickId);
                 return result;
             }
             string shortLinkurl = url;
@@ -269,7 +297,7 @@ namespace molilian.core
                     result.accountName = string.Empty;
                     result.content = content;
                     result.shortLinkurl = url;
-                    result.deeplink_url = GetDeeplink(url);
+                    result.deeplink_url = GetDeeplink(url, clickId);
                     return result;
                 case LinkTypeEnum.other_aff:
                     result.success = false;
@@ -281,7 +309,7 @@ namespace molilian.core
                     result.accountName = string.Empty;
                     result.content = content;
                     result.shortLinkurl = url;
-                    result.deeplink_url = GetDeeplink(url);
+                    result.deeplink_url = GetDeeplink(url, clickId);
                     return result;
                 default:
                     if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(result.itemId) ||
@@ -304,8 +332,8 @@ namespace molilian.core
                         {
                             LinkTypeEnum.other_aff or
                             LinkTypeEnum.baseDomain or
-                            LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
-                            _ => JdUnionPlus.GetDeeplink(string.Empty),
+                            LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl, clickId),
+                            _ => JdUnionPlus.GetDeeplink(string.Empty, clickId),
                         };
                         return result;
                     }
@@ -325,8 +353,8 @@ namespace molilian.core
                 result.shortLinkurl = url;
                 result.deeplink_url = result.link_type switch
                 {
-                    LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
-                    _ => JdUnionPlus.GetDeeplink(string.Empty),
+                    LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl, clickId),
+                    _ => JdUnionPlus.GetDeeplink(string.Empty, clickId),
                 };
                 return result;
             }
@@ -345,14 +373,14 @@ namespace molilian.core
             switch (_account.work_mode)
             {
                 case JdUnionWorkMode.SiteApi:
-                    result = await GetPromotionBySiteAsync(result, url, cancellationToken);
+                    result = await GetPromotionBySiteAsync(result, url, clickId, cancellationToken);
                     break;
                 case JdUnionWorkMode.AffApi:
-                    result = await GetPromotionByAffAsync(result, url, cancellationToken);
+                    result = await GetPromotionByAffAsync(result, url, clickId, cancellationToken);
                     break;
                 case JdUnionWorkMode.Crawler:
                 default:
-                    result = await GetPromotionByCrawlerAsync(result, url, cancellationToken);
+                    result = await GetPromotionByCrawlerAsync(result, url, clickId, cancellationToken);
 
                     break;
             }

+ 2 - 2
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, CancellationToken cancellationToken = default)
+        internal static async Task<UnionCouponDTO> JdCouponAsync(JdPoolDTO account, DataokeDTO api, string content, string clickId, UnionCouponDTO result, CancellationToken cancellationToken = default)
         {
 
             //result.channel = data.channel;
@@ -60,7 +60,7 @@ namespace molilian.core
             result.success = true;
             result.message = "success";
             result.couponAmount = dtkResult.couponAmount;
-            result.deeplink_url = GetDeeplink(dtkResult.couponLink);
+            result.deeplink_url = GetDeeplink(dtkResult.couponLink, clickId);
             result.couponAmount = dtkResult.couponAmount;
             result.itemId = dtkResult.skuId.ToString();
 

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

@@ -28,11 +28,11 @@ namespace molilian.core
 {
     public partial class JdUnionPlus
     {
-        public async Task<JdDataDTO> GetPromotionBySiteAsync(JdDataDTO result, string shortLinkurl, CancellationToken cancellationToken = default)
+        public async Task<JdDataDTO> GetPromotionBySiteAsync(JdDataDTO result, string shortLinkurl, string clickId, CancellationToken cancellationToken = default)
         {
             if (string.IsNullOrEmpty(_account.site_id))
             {
-                return await GetPromotionByAffAsync(result, shortLinkurl, cancellationToken);
+                return await GetPromotionByAffAsync(result, shortLinkurl, clickId, cancellationToken);
             }
 
             string method = "jd.union.open.promotion.common.get";
@@ -67,7 +67,7 @@ namespace molilian.core
                         result.message = "OK";
                         result.shortLinkurl = url;
                         result.content = result.shortLinkurl;
-                        result.deeplink_url = GetDeeplink(result.shortLinkurl);
+                        result.deeplink_url = GetDefaultStyleDeeplink(result.shortLinkurl);
 
                         return result;
                     }
@@ -83,13 +83,13 @@ namespace molilian.core
             result.success = false;
             result.message = "转链失败";
             result.shortLinkurl = shortLinkurl;
-            result.deeplink_url = GetDeeplink(result.shortLinkurl);
+            result.deeplink_url = GetDeeplink(result.shortLinkurl, clickId);
 
             _ = new LoggerLibrary("JdUnion", "promotion_get_error").Info(body).SaveAsync();
             return result;
         }
 
-        public async Task<JdDataDTO> GetPromotionByAffAsync(JdDataDTO result, string shortLinkurl, CancellationToken cancellationToken = default)
+        public async Task<JdDataDTO> GetPromotionByAffAsync(JdDataDTO result, string shortLinkurl, string clickId, CancellationToken cancellationToken = default)
         {
 
             string method = "jd.union.open.promotion.bysubunionid.get";
@@ -122,7 +122,7 @@ namespace molilian.core
                         result.message = "OK";
                         result.shortLinkurl = url;
                         result.content = result.shortLinkurl;
-                        result.deeplink_url = GetDeeplink(result.shortLinkurl);
+                        result.deeplink_url = GetDefaultStyleDeeplink(result.shortLinkurl);
 
                         return result;
                     }
@@ -138,11 +138,11 @@ namespace molilian.core
             result.success = false;
             result.message = "转链失败";
             result.shortLinkurl = shortLinkurl;
-            result.deeplink_url = GetDeeplink(result.shortLinkurl);
+            result.deeplink_url = GetDeeplink(result.shortLinkurl, clickId);
             _ = new LoggerLibrary("JdUnion", "bysubunionid_get_error").Info(body).SaveAsync();
             return result;
         }
-        public async Task<JdDataDTO> GetPromotionByCrawlerAsync(JdDataDTO result, string wareUrl, CancellationToken cancellationToken = default)
+        public async Task<JdDataDTO> GetPromotionByCrawlerAsync(JdDataDTO result, string wareUrl, string clickId, CancellationToken cancellationToken = default)
         {
             string[] parts = wareUrl.Split(new string[] { ".html" }, StringSplitOptions.None);
             if (parts.Length > 1)
@@ -204,7 +204,7 @@ namespace molilian.core
                 result.message = "转链失败";
                 result.reason = "签名失败";
                 result.shortLinkurl = wareUrl;
-                result.deeplink_url = GetDeeplink(result.shortLinkurl);
+                result.deeplink_url = GetDeeplink(result.shortLinkurl, clickId);
                 return result;
             }
 
@@ -250,7 +250,7 @@ namespace molilian.core
                 result.message = "OK";
                 result.shortLinkurl = shortCode;
                 result.content = result.shortLinkurl;
-                result.deeplink_url = GetDeeplink(result.shortLinkurl);
+                result.deeplink_url = GetDefaultStyleDeeplink(result.shortLinkurl);
             }
             else
             {
@@ -259,13 +259,13 @@ namespace molilian.core
                 result.message = "转链失败";
                 result.reason = message;
                 result.shortLinkurl = wareUrl;
-                result.deeplink_url = GetDeeplink(result.shortLinkurl);
+                result.deeplink_url = GetDeeplink(result.shortLinkurl, clickId);
                 _ = new LoggerLibrary("JdUnion", "GetPromotionByCrawlerAsync").Info(body).SaveAsync();
             }
             return result;
         }
 
-        public async Task<JdDataDTO> GetPromotionByCrawlerAsync2(JdDataDTO result, string wareUrl, CancellationToken cancellationToken = default)
+        public async Task<JdDataDTO> GetPromotionByCrawlerAsync2(JdDataDTO result, string wareUrl, string clickId, CancellationToken cancellationToken = default)
         {
             string[] parts = wareUrl.Split(new string[] { ".html" }, StringSplitOptions.None);
             if (parts.Length > 1)
@@ -359,7 +359,7 @@ namespace molilian.core
                 result.message = "OK";
                 result.shortLinkurl = shortCode;
                 result.content = result.shortLinkurl;
-                result.deeplink_url = GetDeeplink(result.shortLinkurl);
+                result.deeplink_url = GetDeeplink(result.shortLinkurl, clickId);
             }
             else
             {
@@ -368,7 +368,7 @@ namespace molilian.core
                 result.message = "转链失败";
                 result.reason = message;
                 result.shortLinkurl = wareUrl;
-                result.deeplink_url = GetDeeplink(result.shortLinkurl);
+                result.deeplink_url = GetDeeplink(result.shortLinkurl, clickId);
                 _ = new LoggerLibrary("JdUnion", "GetPromotionByCrawlerAsync").Info(body).SaveAsync();
             }
             return result;

+ 136 - 0
molilian.core/Plus/VeapiPlus.cs

@@ -61,6 +61,142 @@ namespace molilian.core
         }
 
 
+        public PromotionQueryDTO picSimilaritem(string pic, ref PromotionQueryDTO result)
+        {
+            string url = $"http://api.veapi.cn/tbk/picsimilaritem";
+
+            string base64 = $"data:image/jpeg;base64,{pic}";
+
+            var client = new WebClientUtility();
+            client.SetContentType("application/x-www-form-urlencoded");
+            client.Post("vekey", _key);
+            client.Post("pic", base64);
+            var response = client.Request(url);
+
+
+
+
+            var body = response.Body();
+            var root = body.Convert2JsonElement();
+
+            int error = root.Read<int>("error", 0);
+            bool success = error == 0;
+            string message = root.Read("msg", string.Empty);
+
+
+            result.success = success;
+            if (!success)
+            {
+                result.message = "调用失败";
+                result.reason = message;
+                return result;
+            }
+
+            List<PromotionQueryItemDTO> arr = [];
+
+            var list = root.ElementRead("data");
+            foreach (var e in list.EnumerateArray())
+            {
+                var item = e.ElementRead("Result");
+                string itemId = item.Read<string>("ItemId", string.Empty);
+                string h5_url = $"https://uland.taobao.com/item/edetail?id={itemId}";
+                string deeplink_url = AlimamaPlus.GetDeeplink(h5_url);
+
+                PromotionQueryItemDTO newItem = new PromotionQueryItemDTO();
+                newItem.itemId = itemId;
+                newItem.h5_url = h5_url;
+                newItem.deeplink_url = deeplink_url;
+                newItem.userType = item.Read<string>("UserType", string.Empty);
+                newItem.shopTitle = item.Read<string>("ShopTitle", string.Empty);
+                newItem.itemName = item.Read<string>("Title", string.Empty);
+                newItem.pic = item.Read<string>("PicUrl", string.Empty);
+                newItem.price = item.Read<string>("ReservePrice", string.Empty);
+                newItem.promotionPrice = item.Read<string>("PriceAfterCoupon", string.Empty);
+                newItem.couponAmount = item.Read<string>("CouponAmount", string.Empty);
+                newItem.couponEffectiveStartTime = item.Read<string>("CouponStartTime", string.Empty);
+                newItem.couponEffectiveEndTime = item.Read<string>("CouponEndTime", string.Empty);
+                newItem.sellCountStr = item.Read<string>("sellCountStr", string.Empty);
+                newItem.provcity = item.Read<string>("Provcity", string.Empty);
+                arr.Add(newItem);
+            }
+
+            result.message = "OK";
+            result.reason = string.Empty;
+            result.PromotionImg = arr;
+
+
+
+
+            //PromotionImg
+
+            /*
+             * 
+        public string h5_url { get; set; } = string.Empty;
+        public string deeplink_url { get; set; } = string.Empty;
+        /// <summary>
+        /// 店铺信息-卖家类型:1天猫,0淘宝,3淘特
+        /// </summary>
+        public string userType { get; set; } = string.Empty;
+        public string shopTitle { get; set; } = string.Empty;
+        public string itemId { get; set; } = string.Empty;
+        public string itemName { get; set; } = string.Empty;
+        public string pic { get; set; } = string.Empty;
+        public string price { get; set; } = string.Empty;
+        public string promotionPrice { get; set; } = string.Empty;
+        public string couponAmount { get; set; } = string.Empty;
+        public string couponEffectiveStartTime { get; set; } = string.Empty;
+        public string couponEffectiveEndTime { get; set; } = string.Empty;
+        public string sellCountStr { get; set; } = string.Empty;
+        public string provcity { get; set; } = string.Empty;
+
+
+
+{
+	"error": "0",
+	"msg": "查询成功",
+	"data": [
+		{
+			"RankScore": "0.8065",
+			"Result": {
+				"CategoryName": "跑步鞋",
+				"CommissionRate": "135",
+				"CouponAmount": 50,
+				"CouponEndTime": "2025-01-31",
+				"CouponInfo": "满99.0元减50.0元",
+				"CouponRemainCount": 99656,
+				"CouponStartFee": "99.0",
+				"CouponStartTime": "2024-12-24",
+				"CouponTotalCount": "100000",
+				"ItemId": "jOZk7gxcAfJZ6zGz8bFKjwSJte-Z9Z023UAg5djJmJSRp",
+				"LevelOneCategoryName": "运动鞋new",
+				"MaxCommission": {},
+				"Nick": "",
+				"PicUrl": "https://img.alicdn.com/i2/1994113638/O1CN015M0Aqf1ckFs5UI2eJ_!!0-item_pic.jpg",
+				"PriceAfterCoupon": "109.00",
+				"Provcity": "福建 泉州",
+				"ReservePrice": "259.00",
+				"SellerId": "1994113638",
+				"ShopTitle": "361度户外旗舰店",
+				"ShortTitle": "加绒保暖老爹鞋361女鞋运动鞋女",
+				"SubTitle": "新款加绒女鞋运动鞋",
+				"Title": "361女鞋运动鞋女2024冬季新款加绒保暖棉鞋轻便老爹鞋休闲跑步鞋",
+				"UserType": 1,
+				"Volume": 10,
+				"ZkFinalPrice": "159"
+			}
+		}
+    ]
+	],
+	"request_id": "4eZfpBu"
+}
+             */
+
+
+
+            return result;
+
+        }
+
         public async Task<TkDataDTO> UnionParseAsync(string content, TkDataDTO result, CancellationToken cancellationToken)
         {
             string para = content.UrlEncode();

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

@@ -19,7 +19,7 @@
     <PackageReference Include="AlibabaCloud.SDK.Vpc20160428" Version="6.10.4" />
     <PackageReference Include="AlibabaCloud.TeaConsole" Version="0.1.0" />
     <PackageReference Include="AlibabaCloud.TeaUtil" Version="0.1.19" />
-    <PackageReference Include="dodohold.core" Version="1.0.1.14" />
+    <PackageReference Include="dodohold.core" Version="1.0.1.17" />
     <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" />

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