diff --git a/BBWY.Server.API/Middlewares/ClientVersionValidationMiddleWare.cs b/BBWY.Server.API/Middlewares/ClientVersionValidationMiddleWare.cs index 0ebfc7cd..f80cb7b1 100644 --- a/BBWY.Server.API/Middlewares/ClientVersionValidationMiddleWare.cs +++ b/BBWY.Server.API/Middlewares/ClientVersionValidationMiddleWare.cs @@ -16,7 +16,6 @@ namespace BBWY.Server.API.Middlewares /// private RequestDelegate _next; - private IDictionary apiVersionDictionary; private IOptionsMonitor> _monitor; @@ -24,7 +23,6 @@ namespace BBWY.Server.API.Middlewares { _next = requestDelegate; _monitor = monitor; - apiVersionDictionary = new Dictionary(); } public async Task Invoke(HttpContext context) diff --git a/BBWY.Server.Business/PlatformSDK/APIExecutionTimesRecorder.cs b/BBWY.Server.Business/PlatformSDK/APIExecutionTimesRecorder.cs new file mode 100644 index 00000000..ad04f90e --- /dev/null +++ b/BBWY.Server.Business/PlatformSDK/APIExecutionTimesRecorder.cs @@ -0,0 +1,65 @@ +using BBWY.Common.Models; +using BBWY.Server.Model.Db.Statistics; +using System; +using System.Collections.Concurrent; +using System.Linq; +using Yitter.IdGenerator; + +namespace BBWY.Server.Business +{ + public class APIExecutionTimesRecorder : BaseBusiness, IDenpendency + { + private ConcurrentDictionary apiDictionary; + public APIExecutionTimesRecorder(IFreeSql fsql, + NLogManager nLogManager, + IIdGenerator idGenerator) : base(fsql, nLogManager, idGenerator) + { + this.apiDictionary = new ConcurrentDictionary(); + } + + public void Record(string api) + { + try + { + apiDictionary.AddOrUpdate(api, 1, (k, v) => v + 1); + } + catch { } + } + + public void Flush() + { + var currentRoundList = apiDictionary.Select(kv => new { Api = kv.Key, Count = kv.Value }); + apiDictionary.Clear(); + var currentRoundKeyList = currentRoundList.Select(x => x.Api).ToList(); + var today = DateTime.Now.Date; + var dbList = fsql.Select().Where(x => currentRoundKeyList.Contains(x.Api) && x.Date == today).ToList(); + + var insertList = currentRoundList.Where(x => !dbList.Any(y => y.Api == x.Api)).Select(x => new ApiExecutionTimes + { + Id = idGenerator.NewLong(), + Api = x.Api, + Count = x.Count, + CreateTime = DateTime.Now, + Date = today, + UpdateTime = DateTime.Now + }).ToList(); + + var updateList = currentRoundList.Where(x => dbList.Any(y => y.Api == x.Api)) + .Select(x => fsql.Update() + .Set(a => a.Count + x.Count) + .Where(a => a.Api == x.Api && a.Date == today)) + .ToList(); + + fsql.Transaction(() => + { + if (insertList.Count() > 0) + fsql.Insert(insertList).ExecuteAffrows(); + if (updateList.Count() > 0) + { + foreach (var update in updateList) + update.ExecuteAffrows(); + } + }); + } + } +} diff --git a/BBWY.Server.Business/PlatformSDK/JDBusiness.cs b/BBWY.Server.Business/PlatformSDK/JDBusiness.cs index 25cd6760..412e2c3f 100644 --- a/BBWY.Server.Business/PlatformSDK/JDBusiness.cs +++ b/BBWY.Server.Business/PlatformSDK/JDBusiness.cs @@ -38,7 +38,7 @@ namespace BBWY.Server.Business }; - public JDBusiness(IMemoryCache memoryCache, NLogManager nLogManager, DingDingBusiness dingDingBusiness) : base(memoryCache, nLogManager) + public JDBusiness(IMemoryCache memoryCache, NLogManager nLogManager, DingDingBusiness dingDingBusiness, APIExecutionTimesRecorder apiExecutionTimesRecorder) : base(memoryCache, nLogManager, apiExecutionTimesRecorder) { this.dingDingBusiness = dingDingBusiness; } @@ -364,6 +364,7 @@ namespace BBWY.Server.Business else { var req = new PopOrderEnGetRequest(); + apiExecutionTimesRecorder.Record(req.ApiName); req.optionalFields = searchFields; req.orderId = searchOrderRequest.OrderId; diff --git a/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs b/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs index e14733f7..9bf04a53 100644 --- a/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs +++ b/BBWY.Server.Business/PlatformSDK/PlatformSDKBusiness.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json.Linq; using NLog; using System; +using System.Collections.Concurrent; using System.Collections.Generic; namespace BBWY.Server.Business @@ -22,11 +23,20 @@ namespace BBWY.Server.Business protected NLogManager nLogManager; - public PlatformSDKBusiness(IMemoryCache memoryCache, NLogManager nLogManager) + protected APIExecutionTimesRecorder apiExecutionTimesRecorder; + + public PlatformSDKBusiness(IMemoryCache memoryCache, NLogManager nLogManager, APIExecutionTimesRecorder apiExecutionTimesRecorder) { this.memoryCache = memoryCache; this.nLogManager = nLogManager; this.expirationTimeSpan = TimeSpan.FromMinutes(60); + this.apiExecutionTimesRecorder = apiExecutionTimesRecorder; + } + + public PlatformSDKBusiness(IMemoryCache memoryCache, NLogManager nLogManager) + { + this.memoryCache = memoryCache; + this.nLogManager = nLogManager; } public virtual ProductListResponse GetProductList(SearchProductRequest searchProductRequest) diff --git a/BBWY.Server.Business/TestBusiness.cs b/BBWY.Server.Business/TestBusiness.cs index ac9fa485..c8ed0a23 100644 --- a/BBWY.Server.Business/TestBusiness.cs +++ b/BBWY.Server.Business/TestBusiness.cs @@ -6,9 +6,11 @@ using BBWY.Server.Model.Db; using BBWY.Server.Model.Db.Mds; using BBWY.Server.Model.Dto; using FreeSql; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using Newtonsoft.Json; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -27,6 +29,7 @@ namespace BBWY.Server.Business private OrderSyncBusiness orderSyncBusiness; private TaskSchedulerManager taskSchedulerManager; private PurchaseOrderBusiness purchaseOrderBusiness; + private IMemoryCache memoryCache; public TestBusiness(RestApiService restApiService, IOptions options, FreeSqlMultiDBManager freeSqlMultiDBManager, @@ -35,7 +38,8 @@ namespace BBWY.Server.Business IFreeSql fsql, OrderSyncBusiness orderSyncBusiness, TaskSchedulerManager taskSchedulerManager, - PurchaseOrderBusiness purchaseOrderBusiness) : base(restApiService, options, yunDingBusiness) + PurchaseOrderBusiness purchaseOrderBusiness, + IMemoryCache memoryCache) : base(restApiService, options, yunDingBusiness) { this.freeSqlMultiDBManager = freeSqlMultiDBManager; this.venderBusiness = venderBusiness; @@ -43,6 +47,7 @@ namespace BBWY.Server.Business this.orderSyncBusiness = orderSyncBusiness; this.taskSchedulerManager = taskSchedulerManager; this.purchaseOrderBusiness = purchaseOrderBusiness; + this.memoryCache = memoryCache; } public void SyncVenderId() @@ -411,146 +416,13 @@ namespace BBWY.Server.Business public void Test_20231221() { - var invalidOrderStateList = new List() { Enums.OrderState.已取消, Enums.OrderState.待付款 }; - var shopList = venderBusiness.GetShopList(10224131, Enums.Platform.京东); - var objList = new List<(string id, string shopName, DateTime sjtime, decimal? lastOrderAmount, decimal fto20SearchUv, decimal fto50SearchUv, decimal fto100SearchUv, decimal fto200SearchUv, decimal fto30SearchUv, decimal fto500SearchUv)>(); - var result = new List() { "店铺名,SPU,上架时间,最后一单成交价,推荐访客首次到达20时的搜索访客,推荐访客首次到达50时的搜索访客,推荐访客首次到达100时的搜索访客,推荐访客首次到达200时的搜索访客,推荐访客首次到达300时的搜索访客,推荐访客首次到达50时的搜索访客" }; - foreach (var shop in shopList) - { - Console.WriteLine(shop.ShopName); - var shopId = long.Parse(shop.ShopId); - var productList = fsql.Select().Where(p => p.ShopId == shopId).ToList(); - var productIdList = productList.Select(p => p.Id).ToList(); - - var skuList = fsql.Select() - .InnerJoin((osku, o) => osku.OrderId == o.Id) - .Where((osku, o) => o.ShopId == shopId && - !invalidOrderStateList.Contains(o.OrderState) && - o.IsGift == false && - o.StorageType != Enums.StorageType.SD && - osku.Price > 0) - .GroupBy((osku, o) => osku.ProductId) - .WithTempQuery(g => new { MaxId = g.Max(g.Value.Item1.Id), ProductId = g.Key }) - .From() - .InnerJoin((osku, osku1) => osku1.Id == osku.MaxId) - .ToList((osku, osku1) => new { osku1.ProductId, osku1.OrderId }); - var orderIdList = skuList.Select(s => s.OrderId).Distinct().ToList(); - var orderList = fsql.Select(orderIdList).ToList(o => new Order() { Id = o.Id, ShopId = o.ShopId, OrderTotalPrice = o.OrderTotalPrice }); - - - #region 20 - var _20list = freeSqlMultiDBManager.JDXXfsql.Select() - .Where(s => productIdList.Contains(s.Spu)) - .GroupBy(s => new { s.Spu, s.CreateTime }) - .Having(g => g.Sum(g.Value.StarUv) >= 50) - .OrderBy(g => g.Value.CreateTime) - .ToList(g => new - { - spu = g.Key, - g.Value.CreateTime, - sumSearchUv = g.Sum(g.Value.SearchUv), - sumStarUv = g.Sum(g.Value.StarUv) - }); - - #endregion - - #region 50 - var _50list = freeSqlMultiDBManager.JDXXfsql.Select() - .Where(s => productIdList.Contains(s.Spu)) - .GroupBy(s => new { s.Spu, s.CreateTime }) - .Having(g => g.Sum(g.Value.StarUv) >= 50) - .OrderBy(g => g.Value.CreateTime) - .ToList(g => new - { - spu = g.Key, - g.Value.CreateTime, - sumSearchUv = g.Sum(g.Value.SearchUv), - sumStarUv = g.Sum(g.Value.StarUv) - }); - - #endregion - - #region 100 - var _100list = freeSqlMultiDBManager.JDXXfsql.Select() - .Where(s => productIdList.Contains(s.Spu)) - .GroupBy(s => new { s.Spu, s.CreateTime }) - .Having(g => g.Sum(g.Value.StarUv) >= 100) - .OrderBy(g => g.Value.CreateTime) - .ToList(g => new - { - spu = g.Key, - g.Value.CreateTime, - sumSearchUv = g.Sum(g.Value.SearchUv), - sumStarUv = g.Sum(g.Value.StarUv) - }); - - #endregion - - #region 200 - var _200list = freeSqlMultiDBManager.JDXXfsql.Select() - .Where(s => productIdList.Contains(s.Spu)) - .GroupBy(s => new { s.Spu, s.CreateTime }) - .Having(g => g.Sum(g.Value.StarUv) >= 200) - .OrderBy(g => g.Value.CreateTime) - .ToList(g => new - { - spu = g.Key, - g.Value.CreateTime, - sumSearchUv = g.Sum(g.Value.SearchUv), - sumStarUv = g.Sum(g.Value.StarUv) - }); - - #endregion - - #region 300 - var _300list = freeSqlMultiDBManager.JDXXfsql.Select() - .Where(s => productIdList.Contains(s.Spu)) - .GroupBy(s => new { s.Spu, s.CreateTime }) - .Having(g => g.Sum(g.Value.StarUv) >= 300) - .OrderBy(g => g.Value.CreateTime) - .ToList(g => new - { - spu = g.Key, - g.Value.CreateTime, - sumSearchUv = g.Sum(g.Value.SearchUv), - sumStarUv = g.Sum(g.Value.StarUv) - }); - - #endregion - - #region 500 - var _500list = freeSqlMultiDBManager.JDXXfsql.Select() - .Where(s => productIdList.Contains(s.Spu)) - .GroupBy(s => new { s.Spu, s.CreateTime }) - .Having(g => g.Sum(g.Value.StarUv) >= 500) - .OrderBy(g => g.Value.CreateTime) - .ToList(g => new - { - spu = g.Key, - g.Value.CreateTime, - sumSearchUv = g.Sum(g.Value.SearchUv), - sumStarUv = g.Sum(g.Value.StarUv) - }); - - #endregion - - foreach (var product in productList) - { - var orderTotalPrice = orderList.FirstOrDefault(o => o.Id == (skuList.FirstOrDefault(s => s.ProductId == product.Id)?.OrderId))?.OrderTotalPrice ?? 0M; - var shopName = shop.ShopName; - var sjtime = product.CreateTime; - var fto20SearchUv = _20list.FirstOrDefault(s => s.spu.Spu == product.Id)?.sumSearchUv ?? 0M; - var fto50SearchUv = _50list.FirstOrDefault(s => s.spu.Spu == product.Id)?.sumSearchUv ?? 0M; - var fto100SearchUv = _100list.FirstOrDefault(s => s.spu.Spu == product.Id)?.sumSearchUv ?? 0M; - var fto200SearchUv = _200list.FirstOrDefault(s => s.spu.Spu == product.Id)?.sumSearchUv ?? 0M; - var fto300SearchUv = _300list.FirstOrDefault(s => s.spu.Spu == product.Id)?.sumSearchUv ?? 0M; - var fto500SearchUv = _500list.FirstOrDefault(s => s.spu.Spu == product.Id)?.sumSearchUv ?? 0M; - result.Add($"{shopName},{product.Id},{sjtime},{orderTotalPrice},{fto20SearchUv},{fto50SearchUv},{fto100SearchUv},{fto200SearchUv},{fto300SearchUv},{fto500SearchUv}"); - } - } - - System.IO.File.WriteAllLines(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "result.csv"), result, System.Text.Encoding.UTF8); - Console.WriteLine("结束"); + memoryCache.Set("test123", new ConcurrentDictionary()); + var c = memoryCache.Get>("test123"); + c.AddOrUpdate("123", 1, (k, v) => v + 1); + c.AddOrUpdate("123", 1, (k, v) => v + 1); + Console.WriteLine(c["123"]); + var b = memoryCache.Get>("test123"); + Console.WriteLine(b["123"]); } diff --git a/BBWY.Server.Model/Db/Statistics/ApiExecutionTimes.cs b/BBWY.Server.Model/Db/Statistics/ApiExecutionTimes.cs new file mode 100644 index 00000000..f72995c2 --- /dev/null +++ b/BBWY.Server.Model/Db/Statistics/ApiExecutionTimes.cs @@ -0,0 +1,37 @@ +using FreeSql.DataAnnotations; +using System; + +namespace BBWY.Server.Model.Db.Statistics +{ + + [Table(Name = "apiexecutiontimes", DisableSyncStructure = true)] + public partial class ApiExecutionTimes + { + + [Column(DbType = "bigint", IsPrimary = true)] + public long Id { get; set; } + + [Column(StringLength = 100)] + public string Api { get; set; } + + [Column(DbType = "bigint")] + public long? Count { get; set; } + + [Column(DbType = "datetime")] + public DateTime? CreateTime { get; set; } + + [Column(DbType = "datetime")] + public DateTime? Date { get; set; } + + /// + /// 扩展信息 + /// + [Column(StringLength = 100)] + public string ExtendInfo { get; set; } + + [Column(DbType = "datetime")] + public DateTime? UpdateTime { get; set; } + + } + +} diff --git a/JD.API/Controllers/YunDingController.cs b/JD.API/Controllers/YunDingController.cs index 2bb6f32c..215766e7 100644 --- a/JD.API/Controllers/YunDingController.cs +++ b/JD.API/Controllers/YunDingController.cs @@ -11,10 +11,12 @@ namespace JD.API.Controllers [ApiController] public class YunDingController : ControllerBase { + private APIExecutionTimesRecorder apiExecutionTimesRecorder; private YunDingBusiness yunDingBusiness; - public YunDingController(YunDingBusiness yunDingBusiness) + public YunDingController(YunDingBusiness yunDingBusiness, APIExecutionTimesRecorder apiExecutionTimesRecorder) { this.yunDingBusiness = yunDingBusiness; + this.apiExecutionTimesRecorder = apiExecutionTimesRecorder; } [HttpGet] @@ -22,5 +24,10 @@ namespace JD.API.Controllers { yunDingBusiness.RefreshKey(); } + + public void ApiExecutionTimesFlush() + { + apiExecutionTimesRecorder.Flush(); + } } } diff --git a/JD.API/Startup.cs b/JD.API/Startup.cs index 6e3f8762..9bdcd3e4 100644 --- a/JD.API/Startup.cs +++ b/JD.API/Startup.cs @@ -4,19 +4,14 @@ using JD.API.Filters; using JD.API.Middlewares; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -using System.Threading.Tasks; namespace JD.API { @@ -54,7 +49,6 @@ namespace JD.API p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); }); }); - services.AddControllers(configure => { configure.Filters.Add(); @@ -65,6 +59,7 @@ namespace JD.API //setupAction.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include; //setupAction.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Include; }); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/JD.API/appsettings.json b/JD.API/appsettings.json index d3a0a141..681fe70e 100644 --- a/JD.API/appsettings.json +++ b/JD.API/appsettings.json @@ -7,7 +7,7 @@ } }, "ConnectionStrings": { - "DB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwy_test;charset=utf8;sslmode=none;", + "DB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwy_test;charset=utf8;sslmode=none;" }, "IsEnableSwagger": true, "AllowedHosts": "*",