diff --git a/SBF.API/Controllers/AutoTaskController.cs b/SBF.API/Controllers/AutoTaskController.cs
new file mode 100644
index 0000000..f6dd7f7
--- /dev/null
+++ b/SBF.API/Controllers/AutoTaskController.cs
@@ -0,0 +1,36 @@
+using Microsoft.AspNetCore.Mvc;
+using SBF.Business;
+using SBF.Model.Dto;
+
+namespace SBF.API.Controllers
+{
+
+ public class AutoTaskController : BaseApiController
+ {
+ private AutoTaskBusiness autoTaskBusiness;
+
+ public AutoTaskController(IHttpContextAccessor httpContextAccessor, AutoTaskBusiness autoTaskBusiness) : base(httpContextAccessor)
+ {
+ this.autoTaskBusiness = autoTaskBusiness;
+ }
+
+ ///
+ /// 统计全店托管任务
+ ///
+ [HttpPost]
+ public void StartAllShopTrusteeshipTaskStatistics()
+ {
+ autoTaskBusiness.StartTrusteeshipTaskStatistics(new TrusteeshipTaskMonitorRequest() { ShopId = null });
+ }
+
+ ///
+ /// 统计指定店铺托管任务
+ ///
+ ///
+ [HttpPost]
+ public void StartTrusteeshipTaskStatistics(TrusteeshipTaskMonitorRequest request)
+ {
+ autoTaskBusiness.StartTrusteeshipTaskStatistics(request);
+ }
+ }
+}
diff --git a/SBF.API/Controllers/TrusteeshipController.cs b/SBF.API/Controllers/TrusteeshipController.cs
index b58bc17..bed9fef 100644
--- a/SBF.API/Controllers/TrusteeshipController.cs
+++ b/SBF.API/Controllers/TrusteeshipController.cs
@@ -56,6 +56,16 @@ namespace SBF.API.Controllers
trusteeshipBusiness.StopTrusteeship(id);
}
+ ///
+ /// 删除托管
+ ///
+ ///
+ [HttpPost("id")]
+ public void DeleteTrusteehip([FromRoute] long id)
+ {
+ trusteeshipBusiness.DeleteTrusteehip(id);
+ }
+
///
/// 查询托管任务曲线图详情
///
diff --git a/SBF.Business/AutoTaskBusiness.cs b/SBF.Business/AutoTaskBusiness.cs
new file mode 100644
index 0000000..bf00b04
--- /dev/null
+++ b/SBF.Business/AutoTaskBusiness.cs
@@ -0,0 +1,94 @@
+using FreeSql;
+using SBF.Common.Log;
+using SBF.Common.Models;
+using SBF.Model.Db;
+using SBF.Model.Dto;
+using SiNan.Business;
+using Yitter.IdGenerator;
+
+namespace SBF.Business
+{
+ public class AutoTaskBusiness : BaseBusiness, IDenpendency
+ {
+ private VenderBusiness venderBusiness;
+ private TaskSchedulerManager taskSchedulerManager;
+
+ public AutoTaskBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, VenderBusiness venderBusiness, TaskSchedulerManager taskSchedulerManager) : base(fsql, nLogManager, idGenerator)
+ {
+ this.venderBusiness = venderBusiness;
+ this.taskSchedulerManager = taskSchedulerManager;
+ }
+
+ public void StartTrusteeshipTaskStatistics(TrusteeshipTaskMonitorRequest request)
+ {
+ var shopList = venderBusiness.GetShopList(request.ShopId);
+ foreach (var shop in shopList)
+ {
+ Task.Factory.StartNew(() => TrusteeshipTaskStatistics(long.Parse(shop.ShopId)), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.TaskMonitorScheduler);
+ }
+ }
+
+ private void TrusteeshipTaskStatistics(long shopId)
+ {
+ var inTrusteeshipTaskList = fsql.Select().Where(s => s.ShopId == shopId && s.IsEnd == false && s.IsEnabled == true)
+ .ToList();
+
+ if (inTrusteeshipTaskList.Count() == 0)
+ return;
+
+ var mindate = inTrusteeshipTaskList.Min(s => s.StartTrusteeshipDate);
+ var maxdate = DateTime.Now.Date.AddDays(-1);
+
+ if (maxdate < mindate)
+ return;
+
+ var skuIdList = inTrusteeshipTaskList.Select(s => s.SkuId).Distinct().ToList();
+
+ #region 推广花费
+ var adskudailyAggregationList = fsql.Select()
+ .Where(x => x.ShopId == shopId &&
+ x.Date >= mindate && x.Date <= maxdate &&
+ skuIdList.Contains(x.SkuId))
+ .ToList(x => new
+ {
+ x.Date,
+ x.SkuId,
+ x.CampaignId,
+ x.BusinessType,
+ x.Cost
+ });
+ #endregion
+
+ #region SKU商品营业额
+ var actualAmountList = fsql.Select()
+ .Where(x => x.ShopId == shopId &&
+ x.Date >= mindate && x.Date <= maxdate &&
+ skuIdList.Contains(x.SkuId))
+ .ToList(x => new
+ {
+ x.Date,
+ x.SkuId,
+ //x.Cost,
+ x.ActualAmount
+ });
+
+ #endregion
+
+ IList> updateList = new List>();
+ foreach (var task in inTrusteeshipTaskList)
+ {
+ task.CostInTrusteeship = adskudailyAggregationList.Where(x => x.SkuId == task.SkuId && x.CampaignId == task.CampaignId).Sum(x => x.Cost);
+ task.ActualAmountInTrusteeship = actualAmountList.Where(x => x.SkuId == task.SkuId).Sum(x => x.ActualAmount);
+ var update = fsql.Update(task.Id).Set(t => t.CostInTrusteeship, task.CostInTrusteeship)
+ .Set(t => t.ActualAmountInTrusteeship, task.ActualAmountInTrusteeship);
+ updateList.Add(update);
+ }
+
+ fsql.Transaction(() =>
+ {
+ foreach (var update in updateList)
+ update.ExecuteAffrows();
+ });
+ }
+ }
+}
diff --git a/SBF.Business/TaskSchedulerManager.cs b/SBF.Business/TaskSchedulerManager.cs
index 9c1d764..74e1c2c 100644
--- a/SBF.Business/TaskSchedulerManager.cs
+++ b/SBF.Business/TaskSchedulerManager.cs
@@ -4,18 +4,11 @@ namespace SBF.Business
{
public class TaskSchedulerManager
{
- public LimitedConcurrencyLevelTaskScheduler AggregationSpuGOIScheduler { get; private set; }
-
-
- public LimitedConcurrencyLevelTaskScheduler AggregationCampaignGOIScheduler { get; private set; }
-
- public LimitedConcurrencyLevelTaskScheduler AggregationAdGroupGOIScheduler { get; private set; }
+ public LimitedConcurrencyLevelTaskScheduler TaskMonitorScheduler { get; set; }
public TaskSchedulerManager()
{
- AggregationSpuGOIScheduler = new LimitedConcurrencyLevelTaskScheduler(5);
- AggregationCampaignGOIScheduler = new LimitedConcurrencyLevelTaskScheduler(5);
- AggregationAdGroupGOIScheduler = new LimitedConcurrencyLevelTaskScheduler(5);
+ TaskMonitorScheduler = new LimitedConcurrencyLevelTaskScheduler(5);
}
}
}
diff --git a/SBF.Business/TrusteeshipBusiness.cs b/SBF.Business/TrusteeshipBusiness.cs
index ec4f3d6..3523853 100644
--- a/SBF.Business/TrusteeshipBusiness.cs
+++ b/SBF.Business/TrusteeshipBusiness.cs
@@ -63,7 +63,7 @@ namespace SBF.Business
.WhereIf(skuList.Count() > 1, (ads, c, ad) => skuList.Contains(ads.Sku))
.WhereIf(skuList.Count() == 1, (ads, c, ad) => ads.Sku == skuList[0])
.Where((ads, c, ad) => !fsql.Select()
- .Where(s => s.ShopId == request.ShopId && s.CampaignId == ads.CampaignId && s.SkuId == ads.Sku)
+ .Where(s => s.ShopId == request.ShopId && s.CampaignId == ads.CampaignId && s.SkuId == ads.Sku && s.IsEnabled == true)
.Any())
.GroupBy((ads, c, ad) => new { ads.BusinessType, ads.CampaignId, c.CampaignName, ads.AdGroupId, ad.AdGroupName, ads.AdId, ads.AdName, ads.Sku })
.ToList(g => new SkuJoinPopularizeChannelResponse
@@ -85,8 +85,6 @@ namespace SBF.Business
/// 查询托管任务
///
///
- ///
- ///
///
///
public ListResponse QueryTrusteeship(QueryTrusteeshipRequest request)
@@ -97,7 +95,9 @@ namespace SBF.Business
var list = fsql.Select()
.InnerJoin((t, p, ps) => t.SpuId == p.Id)
.InnerJoin((t, p, ps) => t.SkuId == ps.Id)
- .Where((t, p, ps) => t.ShopId == request.ShopId && t.BusinessType == request.BusinessType)
+ .Where((t, p, ps) => t.ShopId == request.ShopId &&
+ t.BusinessType == request.BusinessType &&
+ t.IsEnabled == true)
.WhereIf(request.Stage != null, (t, p, ps) => p.Stage == request.Stage)
.WhereIf(!string.IsNullOrEmpty(request.Spu), (t, p, ps) => t.SpuId == request.Spu)
.WhereIf(!string.IsNullOrEmpty(request.Sku), (t, p, ps) => t.SkuId == request.Sku)
@@ -126,10 +126,12 @@ namespace SBF.Business
CampaignId = t.CampaignId,
CostInTrusteeship = t.CostInTrusteeship,
CreateTime = t.CreateTime,
+ UpdateTime = t.UpdateTime,
EndTime = t.EndTime,
IsEnd = t.IsEnd,
StartTrusteeshipDate = t.StartTrusteeshipDate,
PolicyType = t.PolicyType,
+ IsEnabled = t.IsEnabled,
Logo = ps.Logo,
Price = ps.Price,
@@ -179,7 +181,7 @@ namespace SBF.Business
{
x.Date,
x.SkuId,
- x.Cost,
+ //x.Cost,
x.ActualAmount
});
@@ -197,8 +199,7 @@ namespace SBF.Business
foreach (var task in list)
{
task.CostByDateList = costList.Where(x => x.SkuId == task.SkuId &&
- x.CampaignId == task.CampaignId &&
- x.BusinessType == task.BusinessType)
+ x.CampaignId == task.CampaignId)
.OrderBy(x => x.Date)
.Select(x => new NumberByDate()
{
@@ -257,7 +258,8 @@ namespace SBF.Business
StartTrusteeshipDate = DateTime.Now.Date.AddDays(1),
ShopId = request.ShopId,
SkuId = x.Sku,
- PolicyType = Model.Enums.PolicyType.成长期策略包
+ PolicyType = Model.Enums.PolicyType.成长期策略包,
+ IsEnabled = true
}).ToList();
var skuIdList = insertList.Select(x => x.SkuId).Distinct().ToList();
@@ -277,16 +279,30 @@ namespace SBF.Business
return;
fsql.Update(id).Set(t => t.IsEnd, true)
.Set(t => t.EndTime, DateTime.Now)
+ .Set(t => t.UpdateTime, DateTime.Now)
.ExecuteAffrows();
}
- public TrusteeshipTaskResponse GetTrusteeshipTaskCurveResponse(long Id)
+ public void DeleteTrusteehip(long id)
{
+ var task = fsql.Select(id).ToOne();
+ if (task == null)
+ throw new BusinessException("托管任务不存在");
+ if (task.IsEnabled == false)
+ return;
+ fsql.Update(id).Set(t => t.IsEnabled, false)
+ .Set(t => t.IsEnd, true)
+ .Set(t => t.EndTime, DateTime.Now)
+ .Set(t => t.UpdateTime, DateTime.Now)
+ .ExecuteAffrows();
+ }
+ public TrusteeshipTaskResponse GetTrusteeshipTaskCurveResponse(long Id)
+ {
var task = fsql.Select()
.InnerJoin((t, p, ps) => t.SpuId == p.Id)
.InnerJoin((t, p, ps) => t.SkuId == ps.Id)
- .Where((t, p, ps) => t.Id == Id)
+ .Where((t, p, ps) => t.Id == Id && t.IsEnabled == true)
.OrderByDescending((t, p, ps) => t.CreateTime)
.ToOne((t, p, ps) => new Sbf_TrusteeshipTask()
{
@@ -307,10 +323,12 @@ namespace SBF.Business
CampaignId = t.CampaignId,
CostInTrusteeship = t.CostInTrusteeship,
CreateTime = t.CreateTime,
+ UpdateTime = t.UpdateTime,
EndTime = t.EndTime,
IsEnd = t.IsEnd,
StartTrusteeshipDate = t.StartTrusteeshipDate,
PolicyType = t.PolicyType,
+ IsEnabled = t.IsEnabled,
Logo = ps.Logo,
Price = ps.Price,
diff --git a/SBF.Business/VenderBusiness.cs b/SBF.Business/VenderBusiness.cs
new file mode 100644
index 0000000..9f9f381
--- /dev/null
+++ b/SBF.Business/VenderBusiness.cs
@@ -0,0 +1,22 @@
+using SBF.Common.Models;
+using SBF.Model.Db.Mds;
+
+namespace SBF.Business
+{
+ public class VenderBusiness : IDenpendency
+ {
+ private FreeSqlMultiDBManager freeSqlMultiDBManager;
+ public VenderBusiness(FreeSqlMultiDBManager freeSqlMultiDBManager)
+ {
+ this.freeSqlMultiDBManager = freeSqlMultiDBManager;
+ }
+
+ public IList GetShopList(long? shopId = null)
+ {
+ return freeSqlMultiDBManager.MDSfsql.Select().Where(s => !string.IsNullOrEmpty(s.ShopId))
+ .WhereIf(shopId != null, s => s.ShopId == shopId.ToString())
+ .Where(s => s.IsEnabled == true)
+ .ToList();
+ }
+ }
+}
diff --git a/SBF.Model/Db/Mds/Shops.cs b/SBF.Model/Db/Mds/Shops.cs
new file mode 100644
index 0000000..8c3193b
--- /dev/null
+++ b/SBF.Model/Db/Mds/Shops.cs
@@ -0,0 +1,192 @@
+using FreeSql.DataAnnotations;
+using System;
+
+namespace SBF.Model.Db.Mds
+{
+
+ [Table(Name = "shops", DisableSyncStructure = true)]
+ public partial class Shops
+ {
+
+ ///
+ /// Id
+ ///
+ [Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
+ public string Id { get; set; }
+
+ ///
+ /// 店铺Key
+ ///
+
+ public string AppKey { get; set; }
+
+ ///
+ /// 店铺Secret
+ ///
+
+ public string AppSecret { get; set; }
+
+ ///
+ /// 店铺Token
+ ///
+
+ public string AppToken { get; set; }
+
+ ///
+ /// 店铺Key 暂定商品管理Key
+ ///
+
+ public string AppKey2 { get; set; }
+
+ ///
+ /// 店铺Secret 暂定商品管理Secret
+ ///
+
+ public string AppSecret2 { get; set; }
+
+ ///
+ /// 店铺Token
+ ///
+
+ public string AppToken2 { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ [Column(DbType = "datetime")]
+ public DateTime CreateTime { get; set; }
+
+ ///
+ /// 创建人Id
+ ///
+ [Column(StringLength = 50)]
+ public string CreatorId { get; set; }
+
+ ///
+ /// 创建人
+ ///
+ [Column(StringLength = 50, IsNullable = false)]
+ public string CreatorRealName { get; set; }
+
+ ///
+ /// 0淘宝,1京东,2阿里巴巴
+ ///
+
+ public int? PlatformId { get; set; }
+
+ ///
+ /// 平台名称
+ ///
+ [Column(StringLength = 50)]
+ public string PlatformName { get; set; }
+
+
+ public string PurchaseAppKey { get; set; }
+
+
+ public string PurchaseAppSecret { get; set; }
+
+ ///
+ /// 采购平台
+ ///
+ [Column(StringLength = 50)]
+ public string PurchasePlatformId { get; set; }
+
+
+ ///
+ /// 商家编号
+ ///
+ public string VenderId { get; set; }
+
+ ///
+ /// 店铺ID
+ ///
+
+ public string ShopId { get; set; }
+
+
+ public string ShopName { get; set; }
+
+ ///
+ /// 店铺账号
+ ///
+
+ public string ShopNick { get; set; }
+
+ ///
+ /// 店铺类型
+ ///
+
+ public string ShopType { get; set; }
+
+ public string ManagePwd { get; set; }
+
+ [Column(DbType = "decimal(11,2)")]
+ public decimal? PlatformCommissionRatio { get; set; }
+
+ ///
+ /// SKU库存安全周转天数
+ ///
+ public int SkuSafeTurnoverDays { get; set; }
+
+ ///
+ /// 钉钉WebHook地址
+ ///
+ [Column(StringLength = 255)]
+ public string DingDingWebHook { get; set; }
+
+ ///
+ /// 钉钉密钥
+ ///
+ [Column(StringLength = 100)]
+ public string DingDingKey { get; set; }
+
+
+ ///
+ /// 司南策略等级
+ ///
+ public int SiNanPolicyLevel { get; set; }
+
+ ///
+ /// 司南钉钉WebHook地址
+ ///
+ [Column(StringLength = 255)]
+ public string SiNanDingDingWebHook { get; set; }
+
+ ///
+ /// 司南钉钉密钥
+ ///
+ [Column(StringLength = 100)]
+ public string SiNanDingDingKey { get; set; }
+
+ ///
+ /// PJZS钉钉WebHook地址
+ ///
+ [Column(StringLength = 255)]
+ public string PJZSDingDingWebHook { get; set; }
+
+ ///
+ /// PJZS钉钉密钥
+ ///
+ [Column(StringLength = 100)]
+ public string PJZSDingDingKey { get; set; }
+
+
+
+ ///
+ /// 齐库钉钉WebHook地址
+ ///
+ [Column(StringLength = 255)]
+ public string QiKuDingDingWebHook { get; set; }
+
+ ///
+ /// 齐库钉钉密钥
+ ///
+ [Column(StringLength = 100)]
+ public string QiKuDingDingKey { get; set; }
+
+ [Column(DbType = "bit", IsNullable = true)]
+ public bool? IsEnabled { get; set; } = true;
+ }
+
+}
diff --git a/SBF.Model/Db/Trusteeship/Sbf_TrusteeshipTask.cs b/SBF.Model/Db/Trusteeship/Sbf_TrusteeshipTask.cs
index c093870..0f3cc8d 100644
--- a/SBF.Model/Db/Trusteeship/Sbf_TrusteeshipTask.cs
+++ b/SBF.Model/Db/Trusteeship/Sbf_TrusteeshipTask.cs
@@ -88,6 +88,12 @@ namespace SBF.Model.Db
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
+ ///
+ /// 更新时间
+ ///
+ [Column(DbType = "datetime")]
+ public DateTime? UpdateTime { get; set; }
+
///
/// 托管结束时间
///
@@ -117,6 +123,11 @@ namespace SBF.Model.Db
[Column(MapType = typeof(int?))]
public Enums.PolicyType? PolicyType { get; set; } = Enums.PolicyType.成长期策略包;
+ ///
+ /// 是否有效
+ ///
+ public bool? IsEnabled { get; set; } = true;
+
#region Product
[Column(IsIgnore = true)]
public DateTime? ProductCreateTime { get; set; }
diff --git a/SBF.Model/Dto/Request/TrusteeshipTaskMonitorRequest.cs b/SBF.Model/Dto/Request/TrusteeshipTaskMonitorRequest.cs
new file mode 100644
index 0000000..306265e
--- /dev/null
+++ b/SBF.Model/Dto/Request/TrusteeshipTaskMonitorRequest.cs
@@ -0,0 +1,7 @@
+namespace SBF.Model.Dto
+{
+ public class TrusteeshipTaskMonitorRequest
+ {
+ public long? ShopId { get; set; }
+ }
+}
diff --git a/SBF.Model/Dto/Response/TrusteeshipTaskResponse.cs b/SBF.Model/Dto/Response/TrusteeshipTaskResponse.cs
index fd4891e..217ecf6 100644
--- a/SBF.Model/Dto/Response/TrusteeshipTaskResponse.cs
+++ b/SBF.Model/Dto/Response/TrusteeshipTaskResponse.cs
@@ -100,6 +100,11 @@ namespace SBF.Model.Dto
///
public DateTime CreateTime { get; set; }
+ ///
+ /// 更新时间
+ ///
+ public DateTime? UpdateTime { get; set; }
+
///
/// 托管结束时间
///
@@ -110,6 +115,11 @@ namespace SBF.Model.Dto
///
public bool IsEnd { get; set; }
+ ///
+ /// 是否有效
+ ///
+ public bool? IsEnabled { get; set; } = true;
+
///
/// 开始计算托管日期
///