飞鱼 1 year ago
parent
commit
a767cec4f2
  1. 5
      BBWYB.Client/App.xaml.cs
  2. 13
      BBWYB.Client/BBWYB.Client.csproj
  3. 4
      BBWYB.Client/GlobalContext.cs
  4. 5
      BBWYB.Client/ViewModels/MainViewModel.cs
  5. 60
      BBWYB.Client/ViewModels/WebVM.cs
  6. 13
      BBWYB.Client/Views/PackPurchaseTask/UpdatePurchaseTaskWindow.xaml.cs
  7. 4
      BBWYB.Client/Views/Web.xaml.cs
  8. 14
      BBWYB.Client/Views/WebB/WebB.xaml
  9. 105
      BBWYB.Client/Views/WebB/WebB.xaml.cs
  10. 14
      BBWYB.Client/Views/WebB/WebB_GoodsSource.xaml
  11. 104
      BBWYB.Client/Views/WebB/WebB_GoodsSource.xaml.cs
  12. 14
      BBWYB.Client/Views/WebB/WebB_KPI.xaml
  13. 87
      BBWYB.Client/Views/WebB/WebB_KPI.xaml.cs
  14. 29
      BBWYB.Common/Extensions/ConverterExtensions.cs
  15. 9
      BBWYB.PurchaserCapture/App.xaml
  16. 22
      BBWYB.PurchaserCapture/App.xaml.cs
  17. 10
      BBWYB.PurchaserCapture/AssemblyInfo.cs
  18. 21
      BBWYB.PurchaserCapture/BBWYB.PurchaserCapture.csproj
  19. 83
      BBWYB.PurchaserCapture/EncryptionExtension.cs
  20. 19
      BBWYB.PurchaserCapture/MainWindow.xaml
  21. 184
      BBWYB.PurchaserCapture/MainWindow.xaml.cs
  22. 94
      BBWYB.PurchaserCapture/Model/Db/OrderPurchaseInfo.cs
  23. 67
      BBWYB.PurchaserCapture/Model/Db/OrderPurchaseSkuInfo.cs
  24. 119
      BBWYB.PurchaserCapture/Model/Db/Purchaser.cs
  25. 53
      BBWYB.PurchaserCapture/Model/Db/Purchaseschemeproduct.cs
  26. 359
      BBWYB.PurchaserCapture/Model/Enums.cs
  27. 33
      BBWYB.Server.API/Controllers/AggregationPurchaseSchemeController.cs
  28. 44
      BBWYB.Server.API/Controllers/AggregationPurchaserController.cs
  29. 8
      BBWYB.Server.API/Controllers/BaseApiController.cs
  30. 61
      BBWYB.Server.API/Controllers/DataRepairController.cs
  31. 10
      BBWYB.Server.API/Controllers/OrderController.cs
  32. 44
      BBWYB.Server.API/Controllers/ProductSyncController.cs
  33. 62
      BBWYB.Server.API/Controllers/PurchaseSchemeController.cs
  34. 74
      BBWYB.Server.API/Controllers/PurchaserController.cs
  35. 84
      BBWYB.Server.API/Controllers/SkuOptimizationController.cs
  36. 37
      BBWYB.Server.API/Controllers/TimeLimitTaskController.cs
  37. 38
      BBWYB.Server.API/Controllers/VenderController.cs
  38. 3
      BBWYB.Server.API/Program.cs
  39. 3
      BBWYB.Server.API/appsettings.json
  40. 147
      BBWYB.Server.Business/Aggregion/AggregionPurchaseSchemeBusiness.cs
  41. 266
      BBWYB.Server.Business/Aggregion/AggregionPurchaserBusiness.cs
  42. 1207
      BBWYB.Server.Business/DataRepair/DataRepairBusiness.cs
  43. 2
      BBWYB.Server.Business/FreeSqlMultiDBManager.cs
  44. 13
      BBWYB.Server.Business/JD/JDBusiness.cs
  45. 207
      BBWYB.Server.Business/Order/OrderBusiness.cs
  46. 342
      BBWYB.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs
  47. 162
      BBWYB.Server.Business/PurchaseScheme/PurchaseProductAPIService.cs
  48. 814
      BBWYB.Server.Business/PurchaseScheme/PurchaseSchemeBusiness.cs
  49. 263
      BBWYB.Server.Business/Purchaser/PurchaserBusiness.cs
  50. 34
      BBWYB.Server.Business/QiKuManager.cs
  51. 954
      BBWYB.Server.Business/SkuOptimization/OptimizationBusiness.cs
  52. 478
      BBWYB.Server.Business/Sync/OrderSyncBusiness.cs
  53. 515
      BBWYB.Server.Business/Sync/ProductSyncBusiness.cs
  54. 7
      BBWYB.Server.Business/TaskSchedulerManager.cs
  55. 298
      BBWYB.Server.Business/TimeLimitTask/TimeLimitRules.cs
  56. 100
      BBWYB.Server.Business/TimeLimitTask/TimeLimitTaskBusiness.cs
  57. 45
      BBWYB.Server.Business/Users/userBusiness.cs
  58. 43
      BBWYB.Server.Business/Vender/VenderBusiness.cs
  59. 57
      BBWYB.Server.Model/Db/BBWY/ProductSku.cs
  60. 130
      BBWYB.Server.Model/Db/BBWY/PurchaseOrderSku.cs
  61. 99
      BBWYB.Server.Model/Db/BBWY/SkuRecentCost.cs
  62. 2
      BBWYB.Server.Model/Db/HY/HY重新生成.bat
  63. 47
      BBWYB.Server.Model/Db/HY/Hycats.cs
  64. 67
      BBWYB.Server.Model/Db/HY/__razor.cshtml.txt
  65. 2
      BBWYB.Server.Model/Db/HY/__重新生成.bat
  66. 132
      BBWYB.Server.Model/Db/MDS/User.cs
  67. 56
      BBWYB.Server.Model/Db/MDS/Userdepartment.cs
  68. 3
      BBWYB.Server.Model/Db/Order/OrderPurchaseInfo.cs
  69. 17
      BBWYB.Server.Model/Db/Order/OrderPurchaseSkuInfo.cs
  70. 18
      BBWYB.Server.Model/Db/Order/OrderSku.cs
  71. 65
      BBWYB.Server.Model/Db/Product/Product.cs
  72. 71
      BBWYB.Server.Model/Db/Product/ProductSku.cs
  73. 48
      BBWYB.Server.Model/Db/Product/Skutotalsaleinfo.cs
  74. 75
      BBWYB.Server.Model/Db/Product/SpuTotalSaleInfo.cs
  75. 70
      BBWYB.Server.Model/Db/PurchaseScheme/PurchaseScheme.cs
  76. 69
      BBWYB.Server.Model/Db/PurchaseScheme/PurchaseSchemeGroup.cs
  77. 42
      BBWYB.Server.Model/Db/PurchaseScheme/PurchaseSchemeProductSkuStatistic.cs
  78. 49
      BBWYB.Server.Model/Db/PurchaseScheme/Purchaser.cs
  79. 13
      BBWYB.Server.Model/Db/PurchaseScheme/Purchaseschemeproductsku.cs
  80. 15
      BBWYB.Server.Model/Db/PurchaseScheme/history/HistoryPurchaseScheme.cs
  81. 39
      BBWYB.Server.Model/Db/PurchaseScheme/history/SkuHistoryPurchaserRelation.cs
  82. 136
      BBWYB.Server.Model/Db/Purchaser/Purchaser.cs
  83. 30
      BBWYB.Server.Model/Db/Purchaser/PurchaserExtendedInfo.cs
  84. 27
      BBWYB.Server.Model/Db/Purchaser/Purchaser_ExtendedInfo_Relation.cs
  85. 57
      BBWYB.Server.Model/Db/SpuOptimization/Skuoptimizationhistory.cs
  86. 45
      BBWYB.Server.Model/Db/SpuOptimization/Skuoptimizationtask.cs
  87. 47
      BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationbargainteamtask.cs
  88. 73
      BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationcompetitivetendertask.cs
  89. 29
      BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationproductskuupdatequotedpricerecord.cs
  90. 60
      BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationpurchasercompetitvetendertask.cs
  91. 92
      BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationtask.cs
  92. 4
      BBWYB.Server.Model/Db/TimeLimitTask/TimeLimitTask.cs
  93. 30
      BBWYB.Server.Model/Dto/Request/LiangKu/BatchLKInventoryAlertRequest.cs
  94. 45
      BBWYB.Server.Model/Dto/Request/Optimization/BatchUpdateCompetitiveTenderQuotationRequest.cs
  95. 44
      BBWYB.Server.Model/Dto/Request/Optimization/QueryNoCompletionOptimizationTaskRequest.cs
  96. 19
      BBWYB.Server.Model/Dto/Request/Order/CompleteOptimizationRequest.cs
  97. 5
      BBWYB.Server.Model/Dto/Request/Order/QueryOrderRequest.cs
  98. 9
      BBWYB.Server.Model/Dto/Request/PageRequest.cs
  99. 40
      BBWYB.Server.Model/Dto/Request/PurchaseScheme/BatchEditPurchaseSkuActualPriceRequest.cs
  100. 9
      BBWYB.Server.Model/Dto/Request/PurchaseScheme/DeleteSchemeGroupRequest.cs

5
BBWYB.Client/App.xaml.cs

@ -32,7 +32,10 @@ namespace BBWYB.Client
#if DEBUG
//齐越山鸡
userToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNTM1MzMwMzI4ODkyMTQ5NzYwIiwidGVhbUlkIjoiMTUxNjk3NDI1MDU0MjUwMTg4OCIsInNvblRlYW1JZHMiOiIxNDM2Mjg4NTAwMjM1MjQzNTIwIiwiZXhwIjoxNjk0NjY5NjkxfQ.cSwro-7bGwOu92YejH9JhMenTai7Mvf99i2paQCmxIw";
//userToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNTM1MzMwMzI4ODkyMTQ5NzYwIiwidGVhbUlkIjoiMTUxNjk3NDI1MDU0MjUwMTg4OCIsInNvblRlYW1JZHMiOiIxNDM2Mjg4NTAwMjM1MjQzNTIwIiwiZXhwIjoxNzI2MzAwNjY0fQ.hPSbgJEuTt0MLy_7YkSJX4rRG3drJAfso-5IS8ZlOkY";
//议价2组
userToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMzk1NzA4MjA4NjU1MzcyMjg4IiwidGVhbUlkIjoiMTYyMDM0MjAxNDcwNjk3ODgxNiIsInNvblRlYW1JZHMiOiIxNzYwOTcxNjg4OTY0NTI2MDgwIiwiZXhwIjoxNzQyNjMwODk0fQ.Vtq2MU1Qd9Oo192udkA01ZAwiQgQxj2m-pkayGZ1d3I";
//拳探店铺 陈默
//userToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNjI0OTUxNjgzNTc2NTAwMjI0IiwidGVhbUlkIjoiMTYyMDM0MjAxNDcwNjk3ODgxNiIsInNvblRlYW1JZHMiOiIxNjIwMzQyMDE0NzA2OTc4ODE2LDE2MjAzNDM4Mjc0NzI1ODQ3MDQsMTYyMDM0NDAzMzczNTg3MjUxMiwxNjIwMzQ0MDkyODI5NDIxNTY4LDE2MjAzNDQxNDA4NTAwMDgwNjQiLCJleHAiOjE3MjA3NjQzMjV9.Q8fiKXCHgvzbm7NDEre-MeoSju_AmC6Ae6eDY22rUAw";

13
BBWYB.Client/BBWYB.Client.csproj

@ -53,17 +53,4 @@
<Resource Include="Resources\Images\defaultItem.png" />
</ItemGroup>
<ItemGroup>
<Compile Update="Views\WebB\WebB_GoodsSource.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Update="Views\WebB\WebB_GoodsSource.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
</Project>

4
BBWYB.Client/GlobalContext.cs

@ -2,7 +2,6 @@
using BBWYB.Client.Helpers;
using BBWYB.Client.Models;
using BBWYB.Client.Views.PackPurchaseTaska;
using BBWYB.Client.Views.WebB;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
@ -21,7 +20,7 @@ namespace BBWYB.Client
{
public GlobalContext()
{
BBWYBApiVersion = "10038";
BBWYBApiVersion = "10041";
}
private User user;
@ -119,7 +118,6 @@ namespace BBWYB.Client
UpdatePurchaseTaskWindow packTask = new(res.Data, originShopName, orderSku);
if (!packTask.IsClosed)
packTask.Show();
WeakReferenceMessenger.Default.Send(new Message_WebB_RefreshPack(null));
//
}
#endregion

5
BBWYB.Client/ViewModels/MainViewModel.cs

@ -1,7 +1,6 @@
using BBWYB.Client.APIServices;
using BBWYB.Client.Models;
using BBWYB.Client.Views.SelectShop;
using BBWYB.Client.Views.WebB;
using BBWYB.Common.Extensions;
using BBWYB.Common.Models;
using CommunityToolkit.Mvvm.Input;
@ -233,10 +232,6 @@ namespace BBWYB.Client.ViewModels
vm.OrderVM.Refresh();
if (vm.IsCreateWareManager)
vm.WareManager.Refresh();
if (SelectedMenuModel?.Name == "订单列表Bata")
{
WeakReferenceMessenger.Default.Send(new Message_WebB_Refresh(null));
}
}
}
catch (Exception ex)

60
BBWYB.Client/ViewModels/WebVM.cs

@ -17,6 +17,7 @@ namespace BBWYB.Client.ViewModels
private MdsApiService mdsApiService;
private MenuModel selectedMenuModel;
private bool isLoading;
private IList<string> managerDepartment;
ShopService shopService;
public GlobalContext GlobalContext { get; set; }
public bool IsLoading { get => isLoading; set { SetProperty(ref isLoading, value); } }
@ -28,6 +29,7 @@ namespace BBWYB.Client.ViewModels
this.mdsApiService = mdsApiService;
this.GlobalContext = globalContext;
this.shopService = shopService;
this.managerDepartment = new List<string>() { "董事办", "财务部", "技术部", "总经办" };
Task.Factory.StartNew(Login);
}
@ -47,36 +49,50 @@ namespace BBWYB.Client.ViewModels
if (mdsUserResponse.Data.SonDepartmentList != null && mdsUserResponse.Data.SonDepartmentList.Count > 0)
GlobalContext.User.SonDepartmentNames = string.Join(',', mdsUserResponse.Data.SonDepartmentList.Select(sd => sd.DepartmentName));
var res = shopService.GetDepartmentList();
if (!res.Success)
throw new Exception(res.Msg);
var allDepartmentList = res.Data.Map<IList<Department>>();
IList<Department> departmentList = null;
var shopList = new List<Shop>();
foreach (var d in allDepartmentList)
shopList.AddRange(d.ShopList);
GlobalContext.User.ShopList = shopList;
if (managerDepartment.Contains(GlobalContext.User.TeamName) ||
managerDepartment.Any(m => GlobalContext.User.SonDepartmentNames.Contains(m)))
{
var res = shopService.GetDepartmentList();
if (!res.Success)
throw new Exception(res.Msg);
var allDepartmentList = res.Data.Map<IList<Department>>();
IList<Department> departmentList = null;
var shopList = new List<Shop>();
foreach (var d in allDepartmentList)
shopList.AddRange(d.ShopList);
GlobalContext.User.ShopList = shopList;
departmentList = allDepartmentList.Where(d => d.Name.Contains("供应链")).ToList();
}
else
{
var response = mdsApiService.GetShopDetailList();
if (!response.Success)
throw new Exception(response.Msg);
departmentList = response.Data.Where(d => d.Name.Contains("供应链")).ToList();
}
//var response = mdsApiService.GetShopDetailList();
//if (!response.Success)
// throw new Exception(response.Msg);
departmentList = allDepartmentList.Where(d => d.Name.Contains("供应链")).ToList();
if (departmentList.Count == 0)
throw new Exception("缺少有效的部门数据");
var shopIds = new List<string>();
foreach (var d in departmentList)
{
if (d.ShopList != null && d.ShopList.Count > 0)
{
foreach (var s in d.ShopList)
shopIds.Add(s.ShopId.ToString());
}
}
//departmentList = allDepartmentList.Where(d => d.Name.Contains("供应链")).ToList();
//if (departmentList.Count == 0)
// throw new Exception("缺少有效的部门数据");
//var shopIds = new List<string>();
//foreach (var d in departmentList)
//{
// if (d.ShopList != null && d.ShopList.Count > 0)
// {
// foreach (var s in d.ShopList)
// shopIds.Add(s.ShopId.ToString());
// }
//}
GlobalContext.User.DepartmentList = departmentList;
WeakReferenceMessenger.Default.Send(new Message_WebB_LoginCompleted(null));

13
BBWYB.Client/Views/PackPurchaseTask/UpdatePurchaseTaskWindow.xaml.cs

@ -1,24 +1,11 @@
using BBWYB.Client.Models;
using BBWYB.Client.Models.APIModel.Response.PackPurchaseTask;
using BBWYB.Client.ViewModels;
using BBWYB.Client.Views.Ware;
using BBWYB.Client.Views.WebB;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using SJ.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace BBWYB.Client.Views.PackPurchaseTaska
{

4
BBWYB.Client/Views/Web.xaml.cs

@ -43,7 +43,9 @@ namespace BBWYB.Client.Views
private void initWebView()
{
#if DEBUG
var url = "http://192.168.1.2:8080";
var url = "http://qtbbwy.qiyue666.com";
//var registerName = "webContext";
//var url = "http://192.168.1.2:8080";
var registerName = "webTestContext";
//var url = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "s.html");
#else

14
BBWYB.Client/Views/WebB/WebB.xaml

@ -1,14 +0,0 @@
<Page x:Class="BBWYB.Client.Views.WebB.WebB"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BBWYB.Client.Views.WebB"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="WebB">
<Grid x:Name="grid">
</Grid>
</Page>

105
BBWYB.Client/Views/WebB/WebB.xaml.cs

@ -1,105 +0,0 @@
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Extensions.DependencyInjection;
using System.Windows;
using System.Windows.Controls;
namespace BBWYB.Client.Views.WebB
{
/// <summary>
/// WebB.xaml 的交互逻辑
/// </summary>
public partial class WebB : Page
{
private WebView2Manager w2m;
private bool isNavigated;
private GlobalContext globalContext;
public WebB()
{
InitializeComponent();
this.Loaded += WebB_Loaded;
this.Unloaded += WebB_Unloaded;
WeakReferenceMessenger.Default.Register<Message_WebB_Refresh>(this, (o, x) =>
{
this.Dispatcher.Invoke(() =>
{
_ = w2m.wb2.ExecuteScriptAsync("window.location.reload();");
});
});
WeakReferenceMessenger.Default.Register<Message_WebB_RefreshPack>(this, (o, x) =>
{
this.Dispatcher.Invoke(() =>
{
_ = w2m.wb2.ExecuteScriptAsync("window.BBWY_B_WebContex('PACK_CONFIG_SUCCESS');");
});
});
}
private void WebB_Unloaded(object sender, RoutedEventArgs e)
{
grid.Children.Remove(w2m.wb2);
//w2m.wb2.Dispose();
w2m.Close();
WeakReferenceMessenger.Default.UnregisterAll(this);
}
private void WebB_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
var sp = (App.Current as App).ServiceProvider;
using (var s = sp.CreateScope())
{
w2m = s.ServiceProvider.GetRequiredService<WebView2Manager>();
globalContext = s.ServiceProvider.GetRequiredService<GlobalContext>();
}
#if DEBUG
var url = "http://192.168.1.8:8080";
var registerName = "webTestContext";
//var url = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "s.html");
#else
var url = "http://qtbbwy.qiyue666.com";
var registerName = "webContext";
#endif
//var url = "http://qtbbwy.qiyue666.com";
w2m.CoreWebView2InitializationCompleted = (e) =>
{
w2m.wb2.CoreWebView2.AddHostObjectToScript(registerName, this.globalContext);
isNavigated = true;
w2m.wb2.CoreWebView2.Navigate(url);
};
w2m.Init("bbwyb_web");
w2m.wb2.SetValue(Grid.RowProperty, 1);
w2m.wb2.Margin = new Thickness(1, 0, 1, 0);
//grid.Children.Clear();
grid.Children.Add(w2m.wb2);
if (w2m.IsInitializationCompleted && !isNavigated)
{
w2m.wb2.CoreWebView2.Navigate(url);
//w2m.wb2.CoreWebView2.NavigateToString(content);
isNavigated = true;
}
}
}
public class Message_WebB_Refresh : ValueChangedMessage<object>
{
public Message_WebB_Refresh(object value) : base(value)
{
}
}
public class Message_WebB_RefreshPack : ValueChangedMessage<object>
{
public Message_WebB_RefreshPack(object value) : base(value)
{
}
}
}

14
BBWYB.Client/Views/WebB/WebB_GoodsSource.xaml

@ -1,14 +0,0 @@
<Page x:Class="BBWYB.Client.Views.WebB.WebB_GoodsSource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BBWYB.Client.Views.WebB"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="WebB">
<Grid x:Name="grid">
</Grid>
</Page>

104
BBWYB.Client/Views/WebB/WebB_GoodsSource.xaml.cs

@ -1,104 +0,0 @@
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Extensions.DependencyInjection;
using System.Windows;
using System.Windows.Controls;
namespace BBWYB.Client.Views.WebB
{
/// <summary>
/// WebB.xaml 的交互逻辑
/// </summary>
public partial class WebB_GoodsSource : Page
{
private WebView2Manager w2m;
private bool isNavigated;
private GlobalContext globalContext;
public WebB_GoodsSource()
{
InitializeComponent();
this.Loaded += WebB_Loaded;
this.Unloaded += WebB_Unloaded;
//WeakReferenceMessenger.Default.Register<Message_WebB_Refresh>(this, (o, x) =>
//{
// this.Dispatcher.Invoke(() =>
// {
// _ = w2m.wb2.ExecuteScriptAsync("window.location.reload();");
// });
//});
//WeakReferenceMessenger.Default.Register<Message_WebB_RefreshPack>(this, (o, x) =>
//{
// this.Dispatcher.Invoke(() =>
// {
// _ = w2m.wb2.ExecuteScriptAsync("window.BBWY_B_WebContex('PACK_CONFIG_SUCCESS');");
// });
//});
}
private void WebB_Unloaded(object sender, RoutedEventArgs e)
{
grid.Children.Remove(w2m.wb2);
//w2m.wb2.Dispose();
w2m.Close();
WeakReferenceMessenger.Default.UnregisterAll(this);
}
private void WebB_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
var sp = (App.Current as App).ServiceProvider;
using (var s = sp.CreateScope())
{
w2m = s.ServiceProvider.GetRequiredService<WebView2Manager>();
globalContext = s.ServiceProvider.GetRequiredService<GlobalContext>();
}
#if DEBUG
var url = "http://192.168.1.2:8080/#/goods-source";
var registerName = "webTestContext";
//var url = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "s.html");
#else
var url = "http://qtbbwy.qiyue666.com/#/goods-source";
var registerName = "webContext";
#endif
w2m.CoreWebView2InitializationCompleted = (e) =>
{
w2m.wb2.CoreWebView2.AddHostObjectToScript(registerName, this.globalContext);
isNavigated = true;
w2m.wb2.CoreWebView2.Navigate(url);
};
w2m.Init("bbwyb_web");
w2m.wb2.SetValue(Grid.RowProperty, 1);
w2m.wb2.Margin = new Thickness(1, 0, 1, 0);
//grid.Children.Clear();
grid.Children.Add(w2m.wb2);
if (w2m.IsInitializationCompleted && !isNavigated)
{
w2m.wb2.CoreWebView2.Navigate(url);
//w2m.wb2.CoreWebView2.NavigateToString(content);
isNavigated = true;
}
}
}
//public class Message_WebB_GoodsSource_Refresh : ValueChangedMessage<object>
//{
// public Message_WebB_GoodsSource_Refresh(object value) : base(value)
// {
// }
//}
//public class Message_WebB_GoodsSource_RefreshPack : ValueChangedMessage<object>
//{
// public Message_WebB_GoodsSource_RefreshPack(object value) : base(value)
// {
// }
//}
}

14
BBWYB.Client/Views/WebB/WebB_KPI.xaml

@ -1,14 +0,0 @@
<Page x:Class="BBWYB.Client.Views.WebB.WebB_KPI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BBWYB.Client.Views.WebB"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="WebB_KPI">
<Grid x:Name="grid">
</Grid>
</Page>

87
BBWYB.Client/Views/WebB/WebB_KPI.xaml.cs

@ -1,87 +0,0 @@
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Windows;
using System.Windows.Controls;
namespace BBWYB.Client.Views.WebB
{
/// <summary>
/// WebB_KPI.xaml 的交互逻辑
/// </summary>
public partial class WebB_KPI : Page
{
private WebView2Manager w2m;
private bool isNavigated;
private GlobalContext globalContext;
public WebB_KPI()
{
InitializeComponent();
this.Loaded += WebB_KPI_Loaded; ;
this.Unloaded += WebB_KPI_Unloaded;
WeakReferenceMessenger.Default.Register<Message_WebBKPI_Refresh>(this, (o, x) =>
{
this.Dispatcher.Invoke(() =>
{
_ = w2m.wb2.ExecuteScriptAsync("window.location.reload();");
});
});
}
private void WebB_KPI_Unloaded(object sender, RoutedEventArgs e)
{
grid.Children.Remove(w2m.wb2);
w2m.Close();
WeakReferenceMessenger.Default.UnregisterAll(this);
}
private void WebB_KPI_Loaded(object sender, RoutedEventArgs e)
{
var sp = (App.Current as App).ServiceProvider;
using (var s = sp.CreateScope())
{
w2m = s.ServiceProvider.GetRequiredService<WebView2Manager>();
globalContext = s.ServiceProvider.GetRequiredService<GlobalContext>();
}
#if DEBUG
var url = "http://localhost:8080/#/performance";
var registerName = "webTestContext";
#else
var url = "http://qtbbwy.qiyue666.com/#/performance";
var registerName = "webContext";
#endif
w2m.CoreWebView2InitializationCompleted = (e) =>
{
w2m.wb2.CoreWebView2.AddHostObjectToScript(registerName, this.globalContext);
isNavigated = true;
w2m.wb2.CoreWebView2.Navigate(url);
};
w2m.Init("bbwyb_web");
w2m.wb2.SetValue(Grid.RowProperty, 1);
w2m.wb2.Margin = new Thickness(1, 0, 1, 0);
//grid.Children.Clear();
grid.Children.Add(w2m.wb2);
if (w2m.IsInitializationCompleted && !isNavigated)
{
w2m.wb2.CoreWebView2.Navigate(url);
//w2m.wb2.CoreWebView2.NavigateToString(content);
isNavigated = true;
}
}
}
public class Message_WebBKPI_Refresh : ValueChangedMessage<object>
{
public Message_WebBKPI_Refresh(object value) : base(value)
{
}
}
}

29
BBWYB.Common/Extensions/ConverterExtensions.cs

@ -0,0 +1,29 @@
namespace BBWYB.Common.Extensions
{
public static class ConverterExtensions
{
public static long? ToInt64(this object? o)
{
try
{
return Convert.ToInt64(o);
}
catch
{
return null;
}
}
public static int? ToInt32(this object? o)
{
try
{
return Convert.ToInt32(o);
}
catch
{
return null;
}
}
}
}

9
BBWYB.PurchaserCapture/App.xaml

@ -0,0 +1,9 @@
<Application x:Class="BBWYB.PurchaserCapture.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BBWYB.PurchaserCapture"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

22
BBWYB.PurchaserCapture/App.xaml.cs

@ -0,0 +1,22 @@
using Microsoft.Extensions.Configuration;
using System.Configuration;
using System.Data;
using System.Windows;
namespace BBWYB.PurchaserCapture
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public IServiceProvider ServiceProvider { get; private set; }
public IConfiguration Configuration { get; private set; }
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
}
}
}

10
BBWYB.PurchaserCapture/AssemblyInfo.cs

@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

21
BBWYB.PurchaserCapture/BBWYB.PurchaserCapture.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
<PackageReference Include="FreeSql" Version="3.2.690" />
<PackageReference Include="FreeSql.Provider.MySql" Version="3.2.690" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.2-mauipre.1.22102.15" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.2-mauipre.1.22102.15" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2210.55" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>

83
BBWYB.PurchaserCapture/EncryptionExtension.cs

@ -0,0 +1,83 @@
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace BBWYB.Common.Extensions
{
public static class EncryptionExtension
{
public static string Md5Encrypt(this string originStr)
{
using (var md5 = MD5.Create())
{
return string.Join(string.Empty, md5.ComputeHash(Encoding.UTF8.GetBytes(originStr)).Select(x => x.ToString("x2")));
}
}
//AES加密 传入,要加密的串和, 解密key
public static string AESEncrypt(this string input)
{
var key = "dataplatform2019";
var ivStr = "1012132405963708";
var encryptKey = Encoding.UTF8.GetBytes(key);
var iv = Encoding.UTF8.GetBytes(ivStr); //偏移量,最小为16
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(encryptKey, iv))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor,
CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(input);
}
var decryptedContent = msEncrypt.ToArray();
return Convert.ToBase64String(decryptedContent);
}
}
}
}
public static string AESDecrypt(this string cipherText)
{
var fullCipher = Convert.FromBase64String(cipherText);
var ivStr = "1012132405963708";
var key = "dataplatform2019";
var iv = Encoding.UTF8.GetBytes(ivStr);
var decryptKey = Encoding.UTF8.GetBytes(key);
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(decryptKey, iv))
{
string result;
using (var msDecrypt = new MemoryStream(fullCipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
public static string Base64Encrypt(this string originStr)
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes(originStr));
}
}
}

19
BBWYB.PurchaserCapture/MainWindow.xaml

@ -0,0 +1,19 @@
<Window x:Class="BBWYB.PurchaserCapture.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BBWYB.PurchaserCapture"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid x:Name="grid">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<TextBox x:Name="txt_url" Grid.Row="1" Height="30" Margin="5,0" VerticalContentAlignment="Center"/>
<TextBlock x:Name="txtInfo" Text="" Grid.Row="2" VerticalAlignment="Center" Margin="5,0,0,0" HorizontalAlignment="Left"/>
<Button x:Name="btn_start" Grid.Row="2" Width="80" Content="开始" Height="25" Click="btn_start_Click"/>
</Grid>
</Window>

184
BBWYB.PurchaserCapture/MainWindow.xaml.cs

@ -0,0 +1,184 @@
using BBWYB.Common.Extensions;
using BBWYB.Server.Model.Db;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using System.IO;
using System.Reflection.Metadata;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using io = System.IO;
namespace BBWYB.PurchaserCapture
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private IFreeSql fsql;
private WebView2 wb2;
private string purchaserId;
private string purchaserMemberId;
public MainWindow()
{
InitializeComponent();
fsql = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwyb;charset=utf8;sslmode=none;").Build();
this.Loaded += MainWindow_Loaded;
}
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
wb2 = new WebView2();
grid.Children.Add(wb2);
var wb2Setting = CoreWebView2Environment.CreateAsync(userDataFolder: io.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AdvUnion.Capturer")).Result;
wb2.CoreWebView2InitializationCompleted += Wb2_CoreWebView2InitializationCompleted;
await wb2.EnsureCoreWebView2Async(wb2Setting);
wb2.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
wb2.CoreWebView2.WebResourceResponseReceived += CoreWebView2_WebResourceResponseReceived;
wb2.CoreWebView2.WebResourceRequested += CoreWebView2_WebResourceRequested;
wb2.CoreWebView2.NavigationCompleted += CoreWebView2_NavigationCompleted;
wb2.CoreWebView2.Navigate("https://www.1688.com");
}
private void CoreWebView2_NavigationCompleted(object? sender, CoreWebView2NavigationCompletedEventArgs e)
{
var scriptBuilder = new StringBuilder();
scriptBuilder.AppendLine("var divElement = document.querySelector('div[style=\"position: relative; display: flex; flex-direction: row;\"]');");
scriptBuilder.AppendLine("var mouseeoverEvent = new MouseEvent('mouseover', {'view': window,'bubbles': true,'cancelable': false});");
scriptBuilder.AppendLine("divElement.dispatchEvent(mouseeoverEvent);");
wb2.CoreWebView2.ExecuteScriptAsync(scriptBuilder.ToString());
}
private async void CoreWebView2_WebResourceResponseReceived(object? sender, CoreWebView2WebResourceResponseReceivedEventArgs e)
{
if (e.Request.Method.ToUpper() != "GET" ||
!e.Request.Uri.StartsWith("https://h5api.m.1688.com/h5/mtop.alibaba.alisite.cbu.server.moduleasyncservice") ||
!e.Request.Uri.Contains("wp_pc_common_header"))
{
Console.WriteLine($"不满足URL规则,已忽略 {e.Request.Uri}");
return;
}
if (e.Response.StatusCode != 200)
{
Console.WriteLine($"HttpCode {e.Response.StatusCode},已忽略 {e.Request.Uri}");
return;
}
try
{
var stream = await e.Response.GetContentAsync();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
sr.Dispose();
var match = Regex.Match(content, "\"bizTypeName\":\\s?\"(.*)\",\"isShili");
if (!match.Success)
{
Console.WriteLine($"bizTypeName解析失败,已忽略 {e.Request.Uri}");
return;
}
var bizTypeName = match.Groups[1].Value;
Console.WriteLine(bizTypeName);
if (!string.IsNullOrEmpty(purchaserId))
{
if (!string.IsNullOrEmpty(purchaserMemberId))
{
if (!content.Contains(purchaserMemberId))
{
Console.WriteLine($"memberId验证失败,已忽略 {e.Request.Uri}");
return;
}
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"更新采购商{purchaserId}");
Console.ResetColor();
fsql.Update<Purchaser>(purchaserId).Set(p => p.ManagmentModeText, bizTypeName).ExecuteAffrows();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void CoreWebView2_WebResourceRequested(object? sender, CoreWebView2WebResourceRequestedEventArgs e)
{
}
private void Wb2_CoreWebView2InitializationCompleted(object? sender, CoreWebView2InitializationCompletedEventArgs e)
{
}
private void SetInfo(string msg)
{
this.Dispatcher.Invoke(() => txtInfo.Text = msg);
}
private void Navigate(string url)
{
this.Dispatcher.Invoke(() =>
{
txt_url.Text = url;
wb2.CoreWebView2.Navigate(url);
});
}
private void btn_start_Click(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
var sk = "order";
//var sk = "consign";
var select = fsql.Select<OrderPurchaseInfo, Purchaser>()
.InnerJoin((opi, p) => opi.PurchaserId == p.Id)
.Where((opi, p) => string.IsNullOrEmpty(p.ManagmentModeText))
.GroupBy((opi, p) => new { p.Id, p.MemberId })
.WithTempQuery(g => new
{
MaxPoId = g.Max(g.Value.Item1.PurchaseOrderId),
PurchaserId = g.Key.Id,
g.Key.MemberId
})
.From<OrderPurchaseSkuInfo>()
.InnerJoin((opi1, ops) => opi1.MaxPoId == ops.PurchaseOrderId)
.GroupBy((opi1, ops) => new { opi1.PurchaserId, opi1.MemberId, opi1.MaxPoId, ops.PurchaseProductId });
var sql = select.ToSql(g => new { g.Key.PurchaserId, g.Key.MemberId, g.Key.MaxPoId, g.Key.PurchaseProductId });
var pspList = select.ToList(g => new { g.Key.PurchaserId, g.Key.MemberId, g.Key.MaxPoId, g.Key.PurchaseProductId });
//var pspList = fsql.Select<PurchaseSchemeProduct, Purchaser>()
// .InnerJoin((psp2, p) => psp2.PurchaserId == p.Id)
// .Where((psp2, p) => string.IsNullOrEmpty(p.ManagmentModeText))
// .GroupBy((psp2, p) => new { p.Id, p.MemberId })
// .WithTempQuery(g => new { MaxId = g.Max(g.Value.Item1.Id), PurchaserId = g.Key.Id, MemberId = g.Key.MemberId })
// .From<PurchaseSchemeProduct>()
// .InnerJoin((psp2, psp1) => psp2.MaxId == psp1.Id)
// .OrderByDescending((psp2, psp1) => Guid.NewGuid())
// .ToList((psp2, psp1) => new
// {
// psp1.PurchaserId,
// psp2.MemberId,
// psp1.PurchaseProductId
// });
for (var i = 0; i < pspList.Count; i++)
{
SetInfo($"{i + 1}/{pspList.Count}");
purchaserId = pspList[i].PurchaserId;
purchaserMemberId = pspList[i].MemberId;
var url = $"https://detail.1688.com/offer/{pspList[i].PurchaseProductId}.html?clickid={Guid.NewGuid().ToString().Md5Encrypt()}&sessionid={Guid.NewGuid().ToString().Md5Encrypt()}&sk={sk}";
Navigate(url);
Thread.Sleep(10000);
}
});
}
}
}

94
BBWYB.PurchaserCapture/Model/Db/OrderPurchaseInfo.cs

@ -0,0 +1,94 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
[Table(Name = "orderpurchaseinfo", DisableSyncStructure = true)]
public partial class OrderPurchaseInfo
{
[Column(IsPrimary = true, IsNullable = false)]
public long Id { get; set; }
[Column(StringLength = 50, IsNullable = false)]
public string OrderId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 꽃뭔瑯뵀Id
/// </summary>
[Column(StringLength = 100)]
public string PurchaseAccountId { get; set; }
/// <summary>
/// 꽃뭔瑯뵀츰냔
/// </summary>
[Column(StringLength = 100)]
public string PurchaseAccountName { get; set; }
[Column(MapType = typeof(int?))]
public Enums.PurchaseMethod? PurchaseMethod { get; set; }
/// <summary>
/// 꽃뭔데Id
/// </summary>
[Column(StringLength = 100)]
public string PurchaseOrderId { get; set; }
[Column(MapType = typeof(int?))]
public Enums.Platform? PurchasePlatform { get; set; }
/// <summary>
/// 꽃뭔�Id
/// </summary>
[Column(StringLength = 100)]
public string PurchaserId { get; set; }
/// <summary>
/// 꽃뭔�츰냔
/// </summary>
[Column(StringLength = 100)]
public string PurchaserName { get; set; }
/// <summary>
/// 듦팟Id
/// </summary>
public long? ShopId { get; set; }
/// <summary>
/// 백橄땐데Sku
/// </summary>
[Column(StringLength = 500)]
public string BelongSkuIds { get; set; }
[Column(DbType = "bit")]
public bool IsEnabled { get; set; } = true;
/// <summary>
/// 꽃뭔데구鬧
/// </summary>
[Column(StringLength = 500)]
public string Remark { get; set; }
/// <summary>
/// �零저袈꽃뭔데珂쇌
/// </summary>
[Column(DbType = "datetime", IsNullable = true)]
public DateTime HistorySettingTime { get; set; }
/// <summary>
/// 꽃뭔데榴檄
/// </summary>
[Column(MapType = typeof(int?))]
public Enums.PurchaseOrderState? OrderState { get; set; }
/// <summary>
/// 角뤠틱송
/// </summary>
[Column(MapType = typeof(int?))]
public Enums.AutoEditOrderPriceType? IsAutoEditOrderPrice { get; set; }
}
}

67
BBWYB.PurchaserCapture/Model/Db/OrderPurchaseSkuInfo.cs

@ -0,0 +1,67 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 采购单Sku表
/// </summary>
[Table(Name = "orderpurchaseskuinfo", DisableSyncStructure = true)]
public partial class OrderPurchaseSkuInfo
{
[Column(IsPrimary = true, StringLength = 100)]
public string Id { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
///// <summary>
///// 物流变更时间
///// </summary>
//[Column(DbType = "datetime")]
//public DateTime? ExpressChangeTime { get; set; }
///// <summary>
///// 物流状态
///// </summary>
//[Column(StringLength = 100)]
//public string ExpressState { get; set; }
/// <summary>
/// 店铺订单Id
/// </summary>
[Column(StringLength = 100)]
public string OrderId { get; set; }
/// <summary>
/// 采购订单Id
/// </summary>
[Column(StringLength = 100)]
public string PurchaseOrderId { get; set; }
/// <summary>
/// 采购商品Id(spu)
/// </summary>
[Column(StringLength = 100)]
public string PurchaseProductId { get; set; }
/// <summary>
/// 采购Sku
/// </summary>
[Column(StringLength = 100)]
public string PurchaseSkuId { get; set; }
/// <summary>
/// 店铺Id
/// </summary>
public long? ShopId { get; set; }
/// <summary>
/// 快递单
/// </summary>
[Column(StringLength = 100)]
public string WaybillNo { get; set; }
}
}

119
BBWYB.PurchaserCapture/Model/Db/Purchaser.cs

@ -0,0 +1,119 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 采购商表
/// </summary>
[Table(Name = "purchaser", DisableSyncStructure = true)]
public partial class Purchaser
{
/// <summary>
/// 采购商Id (1688 SellerUserId)
/// </summary>
[Column(StringLength = 20, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
/// <summary>
/// 采购商Id2 (1688 SellerLoginId)
/// </summary>
[Column(StringLength = 50)]
public string Id2 { get; set; }
/// <summary>
/// 发货地(产地)
/// </summary>
[Column(StringLength = 50)]
public string Location { get; set; }
/// <summary>
/// 经营模式 0贸易 1厂家
/// </summary>
[Column(DbType = "int", MapType = typeof(int))]
public Enums.ManagmentMode? ManagmentMode { get; set; }
/// <summary>
/// 经营模式(文本)
/// </summary>
public string ManagmentModeText { get; set; }
[Column(StringLength = 50)]
public string MemberId { get; set; }
/// <summary>
/// 采购商名称
/// </summary>
[Column(StringLength = 50)]
public string Name { get; set; }
/// <summary>
/// 采购平台
/// </summary>
[Column(MapType = typeof(int?))]
public Enums.Platform? Platform { get; set; }
/// <summary>
/// 商家标签 (超级工厂/实力工厂/实力供应商),可空
/// </summary>
[Column(StringLength = 20)]
public string Tag { get; set; }
/// <summary>
/// 绑定SPU数
/// </summary>
[Column(DbType = "bigint")]
public long? BindingSpuCount { get; set; } = 0;
/// <summary>
/// 采购SPU数
/// </summary>
[Column(DbType = "bigint")]
public long? PurchasedSpuCount { get; set; } = 0;
/// <summary>
/// 绑定SKU数
/// </summary>
[Column(DbType = "bigint")]
public long? BindingSkuCount { get; set; } = 0;
/// <summary>
/// 采购SKU数
/// </summary>
[Column(DbType = "bigint")]
public long? PurchasedSkuCount { get; set; } = 0;
/// <summary>
/// 采购次数/采购订单数
/// </summary>
[Column(DbType = "bigint")]
public long? PurchasedCount { get; set; } = 0;
/// <summary>
/// 采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? PurchasedAmount { get; set; } = 0.00M;
/// <summary>
/// 上次采购时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastPurchasedTime { get; set; }
/// <summary>
/// 最近90天采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? Recent90dPurchasedAmount { get; set; } = 0.00M;
/// <summary>
/// 最近90天采购次数
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? Recent90dPurchasedCount { get; set; } = 0.00M;
}
}

53
BBWYB.PurchaserCapture/Model/Db/Purchaseschemeproduct.cs

@ -0,0 +1,53 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 采购方案商品表
/// </summary>
[Table(Name = "purchaseschemeproduct", DisableSyncStructure = true)]
public partial class PurchaseSchemeProduct
{
/// <summary>
/// 采购商品和采购方案的关系Id
/// </summary>
[Column(IsPrimary = true)]
public long Id { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(StringLength = 50, IsNullable = false)]
public string ProductId { get; set; }
/// <summary>
/// 采购商品Id
/// </summary>
[Column(StringLength = 50, IsNullable = false)]
public string PurchaseProductId { get; set; }
/// <summary>
/// 采购商品链接
/// </summary>
[Column(StringLength = 100)]
public string PurchaseUrl { get; set; }
[Column(StringLength = 50, IsNullable = false)]
public string SkuId { get; set; }
/// <summary>
/// Sku采购方案Id
/// </summary>
public long SkuPurchaseSchemeId { get; set; }
/// <summary>
/// 采购商Id
/// </summary>
[Column(StringLength = 20)]
public string PurchaserId { get; set; }
}
}

359
BBWYB.PurchaserCapture/Model/Enums.cs

@ -0,0 +1,359 @@
namespace BBWYB.Server.Model
{
public class Enums
{
/// <summary>
/// 电商平台 淘宝 = 0,京东 = 1,阿里巴巴 = 2,拼多多 = 3,微信 = 4,拳探 = 10,抖音 = 11
/// </summary>
public enum Platform
{
= 0,
= 1,
= 2,
= 3,
= 4,
= 10,
= 11
}
/// <summary>
/// 采购方式 线上采购 = 0,关联外部单 = 1,手动下单 = 2
/// </summary>
public enum PurchaseMethod
{
线 = 0,
= 1,
= 2
}
/// <summary>
/// 采购单模式 批发 = 0,代发 = 1
/// </summary>
public enum PurchaseOrderMode
{
= 0,
= 1
}
/// <summary>
/// 仓储类型
/// </summary>
public enum StorageType
{
= 0,
= 1,
= 2,
= 3,
SD = 4
}
/// <summary>
/// 订单类型
/// </summary>
public enum OrderType
{
#region JD订单类型
SOP = 22,
LOC = 75,
FBP = 21
#endregion
}
/// <summary>
/// 支付方式
/// </summary>
public enum PayType
{
= 1,
= 2,
= 3,
线 = 4,
= 5,
= 6
}
/// <summary>
/// 订单状态
/// <para>待付款 = 0</para>
/// <para>等待采购 = 1, 部分采购 = 110</para>
/// <para>待发货 = 2, 部分发货 = 120</para>
/// <para>待收货 = 3, 部分收货 = 130</para>
/// <para>已完成 = 4</para>
/// <para>已取消 = 6</para>
/// <para>待验收 = 140</para>
/// <para>待核算 = 150</para>
/// </summary>
public enum OrderState
{
= 0,
= 1,
= 110,
= 2,
= 120,
= 3,
= 130,
= 4,
= 6,
= 140,
= 150
}
/// <summary>
/// 采购单状态 待发货 = 0, 部分发货=1, 待收货 = 10, 部分收货=11, 已签收 = 20, 已取消 = 100
/// </summary>
public enum PurchaseOrderState
{
= 0,
= 1,
= 10,
= 11,
= 20,
= 100
}
/// <summary>
/// 刷单类型
/// </summary>
public enum SDType
{
= 0,
= 1,
= 2,
= 3
}
/// <summary>
/// 订单同步任务状态
/// </summary>
public enum OrderSyncState
{
Running = 0,
End = 1
}
public enum PayChannelType
{
= 0,
= 1,
= 2
}
/// <summary>
/// 服务单处理结果
/// </summary>
public enum ServiceResult
{
退 = 0,
= 1,
= 2,
线 = 3,
= 4,
= 5,
退 = 6,
SD退货 = 7
}
/// <summary>
/// 商品处理方式
/// </summary>
public enum ProductResult
{
_退 = 0,
退 = 1,
退 = 2,
退 = 3,
退 = 4
}
/// <summary>
/// 商品情况
/// </summary>
public enum ProductHealth
{
= 0,
_ = 1,
退退 = 2,
退 = 3,
= 4
}
/// <summary>
/// 排序时间类型 ModifyTime = 0, StartTime = 1
/// </summary>
public enum SortTimeType
{
ModifyTime = 0, StartTime = 1
}
/// <summary>
/// 支付账单类型
/// </summary>
public enum PayBillType
{
= 0,
= 1,
= 2
}
/// <summary>
/// 资金类型
/// </summary>
public enum AuditCapitalType
{
= 0,
退 = 1,
= 2,
退 = 3,
= 4,
= 5,
= 6,
= 7,
= 8,
= 9,
e赊还款 = 10,
= 11,
= 12,
= 13,
= 14,
= 15,
= 16,
= 17,
= 18,
= 19
}
/// <summary>
/// 京东仓库类型 1商家仓 2京东仓
/// </summary>
public enum StockType
{
= 1, = 2
}
/// <summary>
/// 仓库状态 0暂停,1使用
/// </summary>
public enum StockStatus
{
= 0, 使 = 1
}
/// <summary>
/// SKU库存周期 暂无周期=0,增长期=1,稳定期=2,衰退期=3
/// </summary>
public enum SkuStockNumCycleType
{
= 0,
= 1,
= 2,
退 = 3
}
/// <summary>
/// 司南周期 暂无周期 = -1,成长加速期 = 0,成熟利润期 = 1,稳定日销期 = 2,策马奔腾期 = 3
/// </summary>
public enum SiNanCycleType
{
= -1,
= 0,
= 1,
= 2,
= 3
}
/// <summary>
/// 促销任务状态 等待 = 0,进行中 = 1,已完成 = 2, 已停止 = 3
/// </summary>
public enum PromitionTaskStatus
{
= 0,
= 1,
= 2,
= 3
}
/// <summary>
/// AppKey类型 全类型 = 0, 订单管理 = 1, 商品管理 = 2
/// </summary>
public enum AppKeyType
{
= 0, = 1, = 2
}
/// <summary>
/// 采购商品API模式 Spider = 0,OneBound = 1
/// </summary>
public enum PurchaseProductAPIMode
{
Spider = 0,
OneBound = 1
}
/// <summary>
/// 打包配置状态 待配置 = 0,已配置 = 1,需修改 = 2
/// </summary>
public enum PackConfigState
{
= 0,
= 1,
= 2
}
/// <summary>
/// 入仓类型 (发回齐越 = 0, 厂商代发入仓 = 1,其他仓不包装 = 2)
/// </summary>
public enum IntoStoreType
{
= 0, = 1, = 2
}
/// <summary>
/// 限时任务类型 采购任务 = 0, 合格证拟定任务 = 10, 合格证补充任务 = 11, 待核算任务 = 20, 待议价任务 = 30
/// </summary>
public enum TimeLimitTaskType
{
= 0, = 10, = 11, = 20, = 30
}
/// <summary>
/// 平价状态 未平价=0 已平价=1 部分平价=2
/// </summary>
public enum AutoEditOrderPriceType
{
= 0, = 1, = 2
}
/// <summary>
/// 触发优化原因 首次采购 = 0, 首次优化 = 1, 再次优化 = 2
/// </summary>
public enum TriggerOptimizationReason
{
= 0, = 1, = 2
}
/// <summary>
/// 厂家经营模式 贸易 = 0, 厂家 = 1
/// </summary>
public enum ManagmentMode
{
= 0, = 1
}
/// <summary>
/// 厂家扩展信息类型 主营类目 = 0, 标签 = 1
/// </summary>
public enum PurchaserBasicInfoType
{
= 0, = 1
}
/// <summary>
/// 比较运算符 大于 = 0, 小于 = 1, 等于 = 2, 介于 = 3
/// </summary>
public enum ComparisonOperator
{
= 0, = 1, = 2, = 3
}
}
}

33
BBWYB.Server.API/Controllers/AggregationPurchaseSchemeController.cs

@ -0,0 +1,33 @@
using BBWYB.Server.Business;
using Microsoft.AspNetCore.Mvc;
namespace BBWYB.Server.API.Controllers
{
public class AggregationPurchaseSchemeController : BaseApiController
{
private AggregionPurchaseSchemeBusiness aggregionPurchaseSchemeBusiness;
public AggregationPurchaseSchemeController(IHttpContextAccessor httpContextAccessor, AggregionPurchaseSchemeBusiness aggregionPurchaseSchemeBusiness) : base(httpContextAccessor)
{
this.aggregionPurchaseSchemeBusiness = aggregionPurchaseSchemeBusiness;
}
[HttpPost]
public void AutoAggregion()
{
aggregionPurchaseSchemeBusiness.AutoAggregion();
}
[HttpPost]
public void AggregionBySchemeIdList([FromBody]IList<long> schemeIdList)
{
aggregionPurchaseSchemeBusiness.AggregionBySchemeIdList(schemeIdList);
}
[HttpPost]
public void AggregionAllScheme()
{
aggregionPurchaseSchemeBusiness.AggregionAllScheme();
}
}
}

44
BBWYB.Server.API/Controllers/AggregationPurchaserController.cs

@ -0,0 +1,44 @@
using BBWYB.Server.Business;
using Microsoft.AspNetCore.Mvc;
namespace BBWYB.Server.API.Controllers
{
public class AggregationPurchaserController : BaseApiController
{
private AggregionPurchaserBusiness aggregionPurchaserBusiness;
public AggregationPurchaserController(IHttpContextAccessor httpContextAccessor, AggregionPurchaserBusiness aggregionPurchaserBusiness) : base(httpContextAccessor)
{
this.aggregionPurchaserBusiness = aggregionPurchaserBusiness;
}
/// <summary>
/// 采购商聚合
/// </summary>
[HttpPost]
public void AutoAggregion()
{
aggregionPurchaserBusiness.AutoAggregion();
}
/// <summary>
/// 根据指定采购商Id聚合
/// </summary>
/// <param name="purchaserIdList"></param>
[HttpPost]
public void AggregionByPurchaserIdList([FromBody] IList<string> purchaserIdList)
{
aggregionPurchaserBusiness.AggregionByPurchaserIdList(purchaserIdList);
}
/// <summary>
/// 聚合所有采购商
/// </summary>
[HttpPost]
public void AggregionAllPurchaser()
{
aggregionPurchaserBusiness.AggregionAllPurchaser();
}
}
}

8
BBWYB.Server.API/Controllers/BaseApiController.cs

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Cors;
using BBWYB.Common.Models;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
@ -18,7 +19,10 @@ namespace BBWYB.Server.API.Controllers
protected string GetUserId()
{
return httpContextAccessor?.HttpContext?.User.Claims.Where(x => x.Type == "userId")?.FirstOrDefault()?.Value;
var userId = httpContextAccessor?.HttpContext?.User.Claims.Where(x => x.Type == "userId")?.FirstOrDefault()?.Value;
if (string.IsNullOrEmpty(userId))
throw new BusinessException("未从token中获取到userId");
return userId;
}
protected string GetToken()

61
BBWYB.Server.API/Controllers/DataRepairController.cs

@ -78,5 +78,66 @@ namespace BBWYB.Server.API.Controllers
{
dataRepairBusiness.BatchCompleteOrder();
}
[HttpPost]
public void RepairHistoryItemCount()
{
dataRepairBusiness.RepairHistoryItemCount();
}
[HttpPost]
public void RepairPurchaseSkuLastPurchasePriceCost()
{
dataRepairBusiness.RepairPurchaseSkuLastPurchasePriceCost();
}
[HttpPost]
public void RepairPurchaseSchemeLastPurchasePrice()
{
dataRepairBusiness.RepairPurchaseSchemeLastPurchasePrice();
}
[HttpPost]
public void SyncProductCategory()
{ dataRepairBusiness.SyncProductCategory(); }
[HttpPost]
public void SyncPurchaserName()
{
dataRepairBusiness.SyncPurchaserName();
}
/// <summary>
/// 定时补齐采购商主营类目
/// </summary>
[HttpPost]
public void SyncPurchaserCategory()
{
dataRepairBusiness.SyncPurchaserCategory();
}
[HttpPost]
public void RepairPurchaserLocation()
{
dataRepairBusiness.RepairPurchaserLocation();
}
[HttpPost]
public void SyncHyCats()
{
dataRepairBusiness.SyncHyCats();
}
[HttpPost]
public void ExportQTSpuAndJDSku()
{
dataRepairBusiness.ExportQTSpuAndJDSku();
}
[HttpPost]
public void BelongBarginTeam()
{
dataRepairBusiness.BelongBarginTeam();
}
}
}

10
BBWYB.Server.API/Controllers/OrderController.cs

@ -163,5 +163,15 @@ namespace BBWYB.Server.API.Controllers
{
orderBusiness.SetSpecialOrder(request);
}
/// <summary>
/// 完成议价,此操作将完成相同SKU的议价标记和待议价任务
/// </summary>
/// <param name="request"></param>
[HttpPost]
public void CompleteOptimization([FromBody]CompleteOptimizationRequest request)
{
orderBusiness.CompleteOptimization(request);
}
}
}

44
BBWYB.Server.API/Controllers/ProductSyncController.cs

@ -0,0 +1,44 @@
using BBWYB.Server.Business;
using BBWYB.Server.Business.Sync;
using BBWYB.Server.Model;
using Microsoft.AspNetCore.Mvc;
namespace BBWYB.Server.API.Controllers
{
public class ProductSyncController : BaseApiController
{
private ProductSyncBusiness productSyncBusiness;
public ProductSyncController(IHttpContextAccessor httpContextAccessor, ProductSyncBusiness productSyncBusiness) : base(httpContextAccessor)
{
this.productSyncBusiness = productSyncBusiness;
}
/// <summary>
/// 全店同步产品
/// </summary>
[HttpPost]
public void SyncAllShopAllProduct()
{
productSyncBusiness.SyncAllShopAllProduct();
}
/// <summary>
/// 同步所有店铺最近变化产品
/// </summary>
[HttpPost]
public void SyncAllShopUpdateProduct()
{
productSyncBusiness.SyncAllShopUpdateProduct();
}
/// <summary>
/// 同步指定店铺最近变化产品
/// </summary>
/// <param name="shopId"></param>
[HttpPost("{shopId}")]
public void SyncOneShopUpdateProduct([FromRoute] long shopId)
{
productSyncBusiness.SyncOneShopUpdateProduct(shopId);
}
}
}

62
BBWYB.Server.API/Controllers/PurchaseSchemeController.cs

@ -33,7 +33,7 @@ namespace BBWYB.Server.API.Controllers
[HttpPost]
public void EditPurchaseSchemeV2([FromBody] BatchCURDSchemeRequest batchCURDSchemeRequest)
{
purchaseSchemeBusiness.EditPurchaseSchemeV2(batchCURDSchemeRequest);
purchaseSchemeBusiness.EditPurchaseSchemeV2(batchCURDSchemeRequest, GetUserId());
}
/// <summary>
@ -44,6 +44,7 @@ namespace BBWYB.Server.API.Controllers
[HttpPost]
public IList<PurchaseSchemeResponse> GetPurchaseSchemeList([FromBody] QuerySchemeRequest querySchemeRequest)
{
//querySchemeRequest.IncludePurchaserStatisticsInfo = 1;
return purchaseSchemeBusiness.GetPurchaseSchemeList(querySchemeRequest);
}
@ -55,7 +56,18 @@ namespace BBWYB.Server.API.Controllers
[HttpPost]
public IList<PurchaseSchemeGroupResponse> GetPurchaseSchemeAndGroupList(QuerySchemeAndGroupRequest request)
{
return purchaseSchemeBusiness.GetPurchaseSchemeAndGroupList(request);
return purchaseSchemeBusiness.GetPurchaseSchemeAndGroupList(request, GetUserId());
}
/// <summary>
/// 按spu和采购商查询采购方案的采购配件列表并合并返回列表结果 (议价组只查询和自己有关的采购方案)
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public IList<MergePurchaseSchemeProductSkuResponse> GetMergePurchaseSchemeProductSkuBySameSpuAndPurchaser([FromBody] GetMergePurchaseSchemeProductSkuBySameSpuAndPurchaserRequest request)
{
return purchaseSchemeBusiness.GetMergePurchaseSchemeProductSkuBySameSpuAndPurchaser(request, GetUserId());
}
/// <summary>
@ -172,9 +184,51 @@ namespace BBWYB.Server.API.Controllers
/// <param name="request"></param>
/// <returns>最新的采购方案成本</returns>
[HttpDelete]
public decimal DeletePurchaseSku([FromBody]DeletePurchaseSkuRequest request)
{
public decimal DeletePurchaseSku([FromBody] DeletePurchaseSkuRequest request)
{
return purchaseSchemeBusiness.DeletePurchaseSku(request);
}
/// <summary>
/// 设置首选采购方案,同时互斥相同Sku的其他采购方案
/// </summary>
/// <param name="schemeId"></param>
[HttpPost("{schemeId}")]
public void SetFirstPurchaseScheme([FromRoute] long schemeId)
{
purchaseSchemeBusiness.SetFirstPurchaseScheme(schemeId);
}
/// <summary>
/// 查询同spu同采购商的其他配件接口,排除失效配件
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public IList<PurchaseSchemeProductSkuResponse> QuerySameSpuAndSamePurchaserOtherPurchaseSkuList([FromBody] QuerySameSpuAndSamePurchaserOtherPurchaseSkuRequest request)
{
return purchaseSchemeBusiness.QuerySameSpuAndSamePurchaserOtherPurchaseSkuList(request);
}
/// <summary>
/// 批量修改采购配件实际单价
/// </summary>
/// <param name="request"></param>
[HttpPost]
public void BatchEditPurchaseSkuActualPrice([FromBody] BatchEditPurchaseSkuActualPriceRequest request)
{
purchaseSchemeBusiness.BatchEditPurchaseSkuActualPrice(request, GetUserId());
}
/// <summary>
/// 货源标记接口
/// </summary>
/// <param name="requestList"></param>
/// <returns></returns>
[HttpPost]
public IList<GoodsSourceTagResponse> GetGoodsSourceTagsInfo([FromBody] List<QueryGoodsSourceTagRequest> requestList)
{
return purchaseSchemeBusiness.GetGoodsSourceTagsInfo(requestList, GetUserId());
}
}
}

74
BBWYB.Server.API/Controllers/PurchaserController.cs

@ -0,0 +1,74 @@
using BBWYB.Server.Business;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Dto;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace BBWYB.Server.API.Controllers
{
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class PurchaserController : BaseApiController
{
private PurchaserBusiness purchaserBusiness;
public PurchaserController(IHttpContextAccessor httpContextAccessor, PurchaserBusiness purchaserBusiness) : base(httpContextAccessor)
{
this.purchaserBusiness = purchaserBusiness;
}
/// <summary>
/// 根据关键词搜索采购商名称列表
/// </summary>
/// <param name="keywords"></param>
/// <returns></returns>
[HttpGet("{keywords}")]
public ListResponse<string> QueryPurchaserNameList([FromRoute] string keywords)
{
return purchaserBusiness.QueryPurchaserNameList(keywords);
}
/// <summary>
/// 根据关键词搜索采购商产地列表
/// </summary>
/// <param name="keywords"></param>
/// <returns></returns>
[HttpGet("{keywords}")]
public ListResponse<string> QueryPurchaserLocationList([FromRoute] string keywords)
{
return purchaserBusiness.QueryPurchaserLocationList(keywords);
}
/// <summary>
/// 查询采购商列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public ListResponse<PurchaserResponse> QueryPurchaserList([FromBody] QueryPurchaserRequest request)
{
return purchaserBusiness.QueryPurchaserList(request);
}
/// <summary>
/// 查询供应商主营类目或标签列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public ListResponse<PurchaserExtendedInfoResponse> QueryPurchaserCategoryList([FromBody] QueryPurchaserExtendedRequest request)
{
return purchaserBusiness.QueryPurchaserCategoryList(request);
}
/// <summary>
/// 修改供应商扩展信息
/// </summary>
/// <param name="request"></param>
[HttpPost]
public void EditPurchaserExtendedInfo([FromBody] EditPurchaserExtendedInfoRequest request)
{
purchaserBusiness.EditPurchaserExtendedInfo(request);
}
}
}

84
BBWYB.Server.API/Controllers/SkuOptimizationController.cs

@ -0,0 +1,84 @@
using BBWYB.Server.Business;
using BBWYB.Server.Model.Dto;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace BBWYB.Server.API.Controllers
{
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class SkuOptimizationController : BaseApiController
{
private OptimizationBusiness optimizationBusiness;
public SkuOptimizationController(IHttpContextAccessor httpContextAccessor, OptimizationBusiness optimizationBusiness) : base(httpContextAccessor)
{
this.optimizationBusiness = optimizationBusiness;
}
/// <summary>
/// 良库预警通知
/// </summary>
/// <param name="request"></param>
[HttpPost]
[AllowAnonymous]
public void LKInventoryAlertNotification([FromBody] BatchLKInventoryAlertRequest request)
{
optimizationBusiness.LKInventoryAlertNotification(request);
}
/// <summary>
/// 完成待优化任务(当所有议价组的子任务优化完成, 所属待优化任务才会完成)
/// </summary>
/// <param name="taskId">待优化任务Id</param>
[HttpPost("{taskId}")]
public void CompleteOptimization([FromRoute] long taskId)
{
var userId = GetUserId();
optimizationBusiness.CompleteOptimization(taskId, userId);
}
/// <summary>
/// 更新报价
/// </summary>
/// <param name="request"></param>
[HttpPost]
public void BatchUpdateCompetitiveTenderQuotation([FromBody] BatchUpdateCompetitiveTenderQuotationRequest request)
{
optimizationBusiness.BatchUpdateCompetitiveTenderQuotation(request, GetUserId());
}
/// <summary>
/// 查询待议价任务列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public ListResponse<SpuOptimizationTaskResponse> GetNoCompletionSkuOptimizationTask([FromBody] QueryNoCompletionOptimizationTaskRequest request)
{
var userId = GetUserId();
return optimizationBusiness.GetNoCompletionSkuOptimizationTask(request, userId);
}
/// <summary>
/// 删除采购方案分组(包括采购方案和竞标关系)
/// </summary>
/// <param name="request"></param>
[HttpPost]
public void DeleteSchemeGroup(DeleteSchemeGroupFromSpuOptimizationTaskRequest request)
{
var userId = GetUserId();
optimizationBusiness.DeleteSchemeGroup(request, userId);
}
/// <summary>
/// 获取未完成spu优化任务数量
/// </summary>
/// <returns></returns>
[HttpGet]
public long GetNoCompletedSpuOptimizationTaskCount()
{
return optimizationBusiness.GetNoCompletedSpuOptimizationTaskCount();
}
}
}

37
BBWYB.Server.API/Controllers/TimeLimitTaskController.cs

@ -1,4 +1,5 @@
using BBWYB.Server.Business;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Dto;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
@ -28,6 +29,16 @@ namespace BBWYB.Server.API.Controllers
timeLimitTaskBusiness.CheckTask();
}
/// <summary>
/// 修复订单缺失的待核算任务
/// </summary>
[HttpPost]
[AllowAnonymous]
public void RepairOrderComputationTask()
{
timeLimitTaskBusiness.RepairOrderComputationTask();
}
/// <summary>
/// 查询限时任务列表
/// </summary>
@ -45,7 +56,7 @@ namespace BBWYB.Server.API.Controllers
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public IList<TimeLimitTaskStatisticsResponse> TimeOutStatistics([FromBody]QueryTimeOutRequest request)
public IList<TimeLimitTaskStatisticsResponse> TimeOutStatistics([FromBody] QueryTimeOutRequest request)
{
return timeLimitTaskBusiness.TimeOutStatistics(request);
}
@ -59,5 +70,29 @@ namespace BBWYB.Server.API.Controllers
{
timeLimitTaskBusiness.EditTimeLimitTaskRemark(request);
}
/// <summary>
/// 测试计算过期时间
/// </summary>
/// <param name="timeLimitTaskType"></param>
/// <param name="startTime">起点时间</param>
[HttpGet]
[AllowAnonymous]
public DateTime TestExpireTime([FromQuery] Enums.TimeLimitTaskType timeLimitTaskType, [FromQuery] DateTime startTime)
{
return timeLimitTaskBusiness.TestExpireTime(timeLimitTaskType, startTime);
}
/// <summary>
/// 测试计算剩余时间
/// </summary>
/// <param name="expireTime"></param>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public (long, TimeSpan) TextLessTime([FromQuery] DateTime expireTime)
{
return timeLimitTaskBusiness.TextLessTime(expireTime);
}
}
}

38
BBWYB.Server.API/Controllers/VenderController.cs

@ -1,4 +1,6 @@
using BBWYB.Server.Business;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db.MDS;
using BBWYB.Server.Model.Dto;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
@ -22,11 +24,32 @@ namespace BBWYB.Server.API.Controllers
/// <param name="shopSettingRequest"></param>
/// <returns></returns>
[HttpPost]
public long SaveShopSetting([FromBody] ShopSettingRequest shopSettingRequest)
public string SaveShopSetting([FromBody] ShopSettingRequest shopSettingRequest)
{
return venderBusiness.SaveShopSetting(shopSettingRequest);
}
/// <summary>
/// 查询采购账号列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public IList<Purchaseaccount> GetPurchaserList([FromBody] QueryPurchaseAccountRequest request)
{
return venderBusiness.GetPurchaserList(request);
}
/// <summary>
/// 删除采购账号
/// </summary>
/// <param name="purchaseAccountId"></param>
[HttpDelete("{purchaseAccountId}")]
public void DeletePurchaseAccount([FromRoute] long purchaseAccountId)
{
venderBusiness.DeletePurchaseAccount(purchaseAccountId);
}
/// <summary>
/// 查询店铺关联的物流公司列表
/// </summary>
@ -43,9 +66,20 @@ namespace BBWYB.Server.API.Controllers
/// </summary>
/// <returns></returns>
[HttpPost]
public IList<KuaiDi100ExpressCompany> GetKuaiDi100ExpressCompanyList([FromBody]KuaiDi100ExpressSearchRequest request)
public IList<KuaiDi100ExpressCompany> GetKuaiDi100ExpressCompanyList([FromBody] KuaiDi100ExpressSearchRequest request)
{
return venderBusiness.GetKuaiDi100ExpressCompanyList(request);
}
/// <summary>
/// 获取店铺列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public IList<ShopResponse> GetShopList([FromBody] QueryShopRequest request)
{
return venderBusiness.GetShopList(request.ShopId, request.Platform);
}
}
}

3
BBWYB.Server.API/Program.cs

@ -34,11 +34,14 @@ var fsql2 = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.My
var fsql_bbwyc = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, configuration.GetConnectionString("BBWYCDB")).Build();
var fsql_hy = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, configuration.GetConnectionString("HYDB")).Build();
services.AddSingleton(new FreeSqlMultiDBManager()
{
BBWYBfsql = fsql,
MDSfsql = fsql2,
BBWYCfsql = fsql_bbwyc,
HYfsql = fsql_hy
});
services.AddSingleton<NLogManager>();

3
BBWYB.Server.API/appsettings.json

@ -11,7 +11,8 @@
//"DB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwy;charset=utf8;sslmode=none;"
"DB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwyb;charset=utf8;sslmode=none;",
"BBWYCDB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwy_test;charset=utf8;sslmode=none;",
"MDSDB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=mds;charset=utf8;sslmode=none;"
"MDSDB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=mds;charset=utf8;sslmode=none;",
"HYDB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=jdhy;charset=utf8;sslmode=none;"
},
"AllowedSwagger": true,
"Secret": "D96BFA5B-F2AF-45BC-9342-5A55C3F9BBB0",

147
BBWYB.Server.Business/Aggregion/AggregionPurchaseSchemeBusiness.cs

@ -0,0 +1,147 @@
using BBWYB.Common.Log;
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using FreeSql;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
{
public class AggregionPurchaseSchemeBusiness : BaseBusiness, IDenpendency
{
private TaskSchedulerManager taskSchedulerManager;
public AggregionPurchaseSchemeBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, TaskSchedulerManager taskSchedulerManager) : base(fsql, nLogManager, idGenerator)
{
this.taskSchedulerManager = taskSchedulerManager;
}
public void AutoAggregion()
{
var startTime = DateTime.Now.Date.AddDays(-2);
//查询最近有采购的采购方案
var schemeIdList = fsql.Select<OrderPurchaseInfo, OrderPurchaseRelationInfo>()
.InnerJoin((opi, opri) => opi.OrderId == opri.OrderId &&
opi.PurchaseOrderId == opri.PurchaseOrderId)
.Where((opi, opri) => opi.IsEnabled == true &&
opi.UpdateTime >= startTime &&
opri.SchemeId != null)
.Distinct().ToList((opi, opri) => opri.SchemeId.Value);
Task.Factory.StartNew(() => AggregionByGroup(schemeIdList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.AggregationPurchaserTaskScheduler);
}
public void AggregionBySchemeIdList(IList<long> schemeIdList)
{
Task.Factory.StartNew(() => AggregionByGroup(schemeIdList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.AggregationPurchaserTaskScheduler);
}
public void AggregionAllScheme()
{
var schemeIdList = fsql.Select<PurchaseScheme>().ToList(ps => ps.Id);
Task.Factory.StartNew(() => AggregionByGroup(schemeIdList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.AggregationPurchaserTaskScheduler);
}
private void AggregionByGroup(IList<long> schemeIdList)
{
var tempSchemeIdList = new List<long>();
for (var i = 0; i < schemeIdList.Count(); i++)
{
tempSchemeIdList.Add(schemeIdList[i]);
if (i != 0 && i % 30 == 0)
{
Console.WriteLine($"聚合{i + 1}/{schemeIdList.Count()}");
Aggregion(tempSchemeIdList);
tempSchemeIdList.Clear();
Thread.Sleep(2000);
}
}
if (tempSchemeIdList.Count() > 0)
{
Console.WriteLine($"最后聚合");
Aggregion(tempSchemeIdList);
tempSchemeIdList.Clear();
}
}
private void Aggregion(IList<long> schemeIdList)
{
var pssIdList = fsql.Select<PurchaseSchemeProductSku>()
.Where(pss => schemeIdList.Contains(pss.SkuPurchaseSchemeId))
.Distinct()
.ToList(pss => pss.PurchaseSkuId);
var dbStatisticList = fsql.Select<PurchaseSchemeProductSkuStatistic>(pssIdList).ToList();
List<PurchaseSchemeProductSkuStatistic> insertStatisticList = new List<PurchaseSchemeProductSkuStatistic>();
List<IUpdate<PurchaseSchemeProductSkuStatistic>> updateStatisticList = new List<IUpdate<PurchaseSchemeProductSkuStatistic>>();
#region 采购件数/采购金额
var aggregationItemCountAndAmountList = fsql.Select<OrderPurchaseInfo, OrderPurchaseSkuInfo>()
.InnerJoin((opi, opsi) => opi.OrderId == opsi.OrderId &&
opi.PurchaseOrderId == opsi.PurchaseOrderId)
.Where((opi, opsi) => opi.IsEnabled == true && pssIdList.Contains(opsi.PurchaseSkuId))
.GroupBy((opi, opsi) => opsi.PurchaseSkuId)
.ToList(g => new
{
PurchaseSkuId = g.Key,
PurchasedItemCount = g.Sum(g.Value.Item2.PurchasedItemCount),
PurchasedAmount = g.Sum(g.Value.Item2.PurchasedAmount)
});
#endregion
#region 最近采购单价
var recentPurchaseSkuList = fsql.Select<OrderPurchaseInfo, OrderPurchaseSkuInfo>()
.InnerJoin((opi, opsi) => opi.OrderId == opsi.OrderId &&
opi.PurchaseOrderId == opsi.PurchaseOrderId)
.Where((opi, opsi) => opi.IsEnabled == true && pssIdList.Contains(opsi.PurchaseSkuId))
.GroupBy((opi, opsi) => opsi.PurchaseSkuId)
.WithTempQuery(g => new { MaxId = g.Max(g.Value.Item2.Id) })
.From<OrderPurchaseSkuInfo>()
.InnerJoin((opsi, opsi2) => opsi.MaxId == opsi2.Id)
.ToList((opsi, opsi2) => opsi2);
#endregion
foreach (var purchaseSkuId in pssIdList)
{
var statistic = dbStatisticList.FirstOrDefault(x => x.PurchaseSkuId == purchaseSkuId);
var aggregation = aggregationItemCountAndAmountList.FirstOrDefault(x => x.PurchaseSkuId == purchaseSkuId);
var recent = recentPurchaseSkuList.FirstOrDefault(x => x.PurchaseSkuId == purchaseSkuId);
if (statistic == null)
{
insertStatisticList.Add(new PurchaseSchemeProductSkuStatistic()
{
PurchaseSkuId = purchaseSkuId,
CreateTime = DateTime.Now,
PurchasedAmount = aggregation?.PurchasedAmount ?? 0M,
PurchasedItemCount = Convert.ToInt32(aggregation?.PurchasedItemCount ?? 0M),
LastPurchasedPrice = recent?.PurchasedPrice,
LastPurchasedTime = recent?.CreateTime
});
}
else
{
if (aggregation != null || recent != null)
{
var update = fsql.Update<PurchaseSchemeProductSkuStatistic>(purchaseSkuId)
.SetIf(aggregation != null, x => x.PurchasedAmount, aggregation?.PurchasedAmount ?? 0M)
.SetIf(aggregation != null, x => x.PurchasedItemCount, Convert.ToInt32(aggregation?.PurchasedItemCount ?? 0))
.SetIf(recent != null, x => x.LastPurchasedPrice, recent.PurchasedPrice)
.SetIf(recent != null, x => x.LastPurchasedTime, recent.CreateTime);
updateStatisticList.Add(update);
}
}
}
fsql.Transaction(() =>
{
if (insertStatisticList.Count() > 0)
fsql.Insert(insertStatisticList).ExecuteAffrows();
if (updateStatisticList.Count() > 0)
{
foreach (var update in updateStatisticList)
update.ExecuteAffrows();
}
});
}
}
}

266
BBWYB.Server.Business/Aggregion/AggregionPurchaserBusiness.cs

@ -0,0 +1,266 @@
using BBWYB.Common.Log;
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using FreeSql;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
{
public class AggregionPurchaserBusiness : BaseBusiness, IDenpendency
{
private TaskSchedulerManager taskSchedulerManager;
public AggregionPurchaserBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, TaskSchedulerManager taskSchedulerManager) : base(fsql, nLogManager, idGenerator)
{
this.taskSchedulerManager = taskSchedulerManager;
}
public void AutoAggregion()
{
var startTime = DateTime.Now.Date.AddDays(-90);
//查询最近有采购的采购商列表
var purchaserIdList = fsql.Select<OrderPurchaseInfo, Order>()
.InnerJoin((opi, o) => opi.OrderId == o.Id)
.Where((opi, o) => opi.IsEnabled == true &&
o.OrderState != Enums.OrderState. &&
o.StartTime >= startTime &&
!string.IsNullOrEmpty(opi.PurchaserId))
.Distinct()
.ToList((opi, o) => opi.PurchaserId);
Task.Factory.StartNew(() => AggregionByGroup(purchaserIdList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.AggregationPurchaserTaskScheduler);
}
public void AggregionByPurchaserIdList(IList<string> purchaserIdList)
{
Task.Factory.StartNew(() => AggregionByGroup(purchaserIdList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.AggregationPurchaserTaskScheduler);
}
public void AggregionAllPurchaser()
{
var purchaserIdList = fsql.Select<Purchaser>().ToList(p => p.Id);
Task.Factory.StartNew(() => AggregionByGroup(purchaserIdList), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.AggregationPurchaserTaskScheduler);
}
private void AggregionByGroup(IList<string> purchaserIdList)
{
var tempPurchaserIdList = new List<string>();
for (var i = 0; i < purchaserIdList.Count(); i++)
{
tempPurchaserIdList.Add(purchaserIdList[i]);
if (i != 0 && i % 30 == 0)
{
Console.WriteLine($"聚合{i + 1}/{purchaserIdList.Count()}");
Aggregion(tempPurchaserIdList);
tempPurchaserIdList.Clear();
Thread.Sleep(2000);
}
}
if (tempPurchaserIdList.Count() > 0)
{
Console.WriteLine($"最后聚合");
Aggregion(tempPurchaserIdList);
tempPurchaserIdList.Clear();
}
}
private void Aggregion(IList<string> purchaserIdList)
{
List<IUpdate<Purchaser>> updatePurchaserList = new List<IUpdate<Purchaser>>();
List<long> deletePeiList = new List<long>();
List<Purchaser_ExtendedInfo_Relation> insertPeiList = new List<Purchaser_ExtendedInfo_Relation>();
List<Purchaser_ExtendedInfo_Relation> dbPeiList = fsql.Select<Purchaser_ExtendedInfo_Relation>()
.Where(pei => pei.ExtendedType == Enums.PurchaserBasicInfoType. &&
purchaserIdList.Contains(pei.PurchaserId))
.ToList();
var pspList = fsql.Select<PurchaseSchemeProduct, Product>()
.InnerJoin((psp, p) => psp.ProductId == p.Id)
.Where((psp, p) => p.CategoryId != null && purchaserIdList.Contains(psp.PurchaserId))
.ToList((psp, p) => new
{
psp.PurchaserId,
psp.ProductId,
p.CategoryId
});
#region 查询SPU绑定数/SKU绑定数
var bindList = fsql.Select<PurchaseSchemeProduct, PurchaseScheme>()
.InnerJoin((psp, psc) => psp.SkuPurchaseSchemeId == psc.Id)
.Where((psp, psc) => purchaserIdList.Contains(psp.PurchaserId))
.GroupBy((psp, psc) => new { psp.PurchaserId, psp.ProductId, psp.SkuId })
.ToList(g => new
{
g.Key.PurchaserId,
g.Key.ProductId,
g.Key.SkuId
});
#endregion
#region 查询SPU采购数/SKU采购数
var purchasedList = fsql.Select<ProductSku, OrderPurchaseRelationInfo, OrderPurchaseInfo, Order>()
.InnerJoin((ps, ori, opi, o) => ps.Id == ori.BelongSkuId)
.InnerJoin((ps, ori, opi, o) => ori.PurchaseOrderId == opi.PurchaseOrderId &&
ori.OrderId == opi.OrderId)
.InnerJoin((ps, ori, opi, o) => opi.OrderId == o.Id)
.Where((ps, ori, opi, o) => o.OrderState != Enums.OrderState. &&
opi.IsEnabled == true &&
purchaserIdList.Contains(opi.PurchaserId))
.GroupBy((ps, ori, opi, o) => new { opi.PurchaserId, ps.Id, ps.ProductId })
.ToList(g => new
{
g.Key.PurchaserId,
g.Key.ProductId,
SkuId = g.Key.Id
});
#endregion
#region 查询订单数/最近采购时间
var poList = fsql.Select<OrderPurchaseInfo, Order>()
.InnerJoin((opi, o) => opi.OrderId == o.Id)
.Where((opi, o) => opi.IsEnabled == true &&
o.OrderState != Enums.OrderState. &&
purchaserIdList.Contains(opi.PurchaserId))
.GroupBy((opi, o) => opi.PurchaserId)
.ToList(g => new
{
PurchaserId = g.Key,
Count = g.Count(),
MaxPurchaseTime = g.Max(g.Value.Item1.CreateTime)
});
#endregion
#region 查询最近90天采购数量
var recent90d = DateTime.Now.Date.AddDays(-90);
var recent90dPurchasedCountList = fsql.Select<OrderPurchaseInfo, Order>()
.InnerJoin((opi, o) => opi.OrderId == o.Id)
.Where((opi, o) => o.OrderState != Enums.OrderState. &&
opi.IsEnabled == true &&
opi.CreateTime >= recent90d &&
purchaserIdList.Contains(opi.PurchaserId))
.GroupBy((opi, o) => opi.PurchaserId)
.ToList(g => new
{
PurchaserId = g.Key,
Count = g.Count(),
});
#endregion
#region 查询采购金额
var purchasedAmountList = fsql.Select<OrderCostDetail, Order, OrderPurchaseInfo>()
.InnerJoin((ocd, o, opi) => ocd.OrderId == o.Id)
.InnerJoin((ocd, o, opi) => o.Id == opi.OrderId)
.Where((ocd, o, opi) => o.OrderState != Enums.OrderState. &&
ocd.IsEnabled == true &&
opi.IsEnabled == true &&
purchaserIdList.Contains(opi.PurchaserId))
.GroupBy((ocd, o, opi) => opi.PurchaserId)
.ToList(g => new
{
PurchaserId = g.Key,
PurchasedAmount = g.Sum(g.Value.Item1.SkuAmount + g.Value.Item1.PurchaseFreight)
});
#endregion
#region 查询最近90天采购金额
var recent90dPurchasedAmountList = fsql.Select<OrderCostDetail, Order, OrderPurchaseInfo>()
.InnerJoin((ocd, o, opi) => ocd.OrderId == o.Id)
.InnerJoin((ocd, o, opi) => o.Id == opi.OrderId)
.Where((ocd, o, opi) => o.OrderState != Enums.OrderState. &&
ocd.IsEnabled == true &&
opi.IsEnabled == true &&
opi.CreateTime >= recent90d &&
purchaserIdList.Contains(opi.PurchaserId))
.GroupBy((ocd, o, opi) => opi.PurchaserId)
.ToList(g => new
{
PurchaserId = g.Key,
PurchasedAmount = g.Sum(g.Value.Item1.SkuAmount + g.Value.Item1.PurchaseFreight)
});
#endregion
foreach (var purchaserId in purchaserIdList)
{
#region SPU绑定数/SKU绑定数
var currentBindList = bindList.Where(x => x.PurchaserId == purchaserId).ToList();
var bindingSpuCount = currentBindList.Select(x => x.ProductId).Distinct().Count();
var bindingSkuCount = currentBindList.Select(x => x.SkuId).Count();
#endregion
#region SPU采购数/SKU采购数
var currentPurchasedList = purchasedList.Where(x => x.PurchaserId == purchaserId).ToList();
var purchasedSpuCount = currentPurchasedList.Select(x => x.ProductId).Distinct().Count();
var purchasedSkuCount = currentPurchasedList.Select(x => x.SkuId).Count();
#endregion
#region 订单数/最近采购时间
var purchasedCountAndTime = poList.FirstOrDefault(x => x.PurchaserId == purchaserId);
var purchasedCount = purchasedCountAndTime?.Count ?? 0;
var lastPurchasedTime = purchasedCountAndTime?.MaxPurchaseTime;
#endregion
#region 采购金额
var purchasedAmount = purchasedAmountList.FirstOrDefault(x => x.PurchaserId == purchaserId)?.PurchasedAmount ?? 0;
#endregion
#region 最近90天采购金额
var recent90dPurchasedAmount = recent90dPurchasedAmountList.FirstOrDefault(x => x.PurchaserId == purchaserId)?.PurchasedAmount ?? 0;
#endregion
#region 最近90天采购数量
var recent90dPurchasedCount = recent90dPurchasedCountList.FirstOrDefault(x => x.PurchaserId == purchaserId)?.Count ?? 0;
#endregion
#region 主营类目
{
var currentDbPeiList = dbPeiList.Where(pei => pei.PurchaserId == purchaserId).ToList();
var currentDbPspList = pspList.Where(psp => psp.PurchaserId == purchaserId).ToList();
var currentDeletePeiList = currentDbPeiList.Where(pei => !currentDbPspList.Any(psp => psp.PurchaserId == pei.PurchaserId &&
psp.CategoryId == pei.ExtendedInfoId))
.Select(pei => pei.Id).ToList();
if (currentDeletePeiList.Count() > 0)
deletePeiList.AddRange(currentDeletePeiList);
var currentInsertPeiList = currentDbPspList.Where(psp => !currentDbPeiList.Any(pei => pei.PurchaserId == psp.PurchaserId &&
pei.ExtendedInfoId == psp.CategoryId))
.GroupBy(psp => psp.CategoryId)
.Select(g => new Purchaser_ExtendedInfo_Relation()
{
Id = idGenerator.NewLong(),
ExtendedInfoId = g.Key,
ExtendedType = Enums.PurchaserBasicInfoType.,
PurchaserId = purchaserId
}).ToList();
if (currentInsertPeiList.Count() > 0)
insertPeiList.AddRange(currentInsertPeiList);
}
#endregion
var update = fsql.Update<Purchaser>(purchaserId)
.Set(p => p.BindingSpuCount, bindingSpuCount)
.Set(p => p.BindingSkuCount, bindingSkuCount)
.Set(p => p.PurchasedSpuCount, purchasedSpuCount)
.Set(p => p.PurchasedSkuCount, purchasedSkuCount)
.Set(p => p.PurchasedCount, purchasedCount)
.Set(p => p.PurchasedAmount, purchasedAmount)
.Set(p => p.LastPurchasedTime, lastPurchasedTime)
.Set(p => p.Recent90dPurchasedAmount, recent90dPurchasedAmount)
.Set(p => p.Recent90dPurchasedCount, recent90dPurchasedCount);
updatePurchaserList.Add(update);
}
fsql.Transaction(() =>
{
foreach (var update in updatePurchaserList)
update.ExecuteAffrows();
if (deletePeiList.Count() > 0)
fsql.Delete<Purchaser_ExtendedInfo_Relation>(deletePeiList).ExecuteAffrows();
if (insertPeiList.Count() > 0)
fsql.Insert(insertPeiList).ExecuteAffrows();
});
}
}
}

1207
BBWYB.Server.Business/DataRepair/DataRepairBusiness.cs

File diff suppressed because it is too large

2
BBWYB.Server.Business/FreeSqlMultiDBManager.cs

@ -6,5 +6,7 @@
public IFreeSql MDSfsql { get; set; }
public IFreeSql BBWYCfsql { get; set; }
public IFreeSql HYfsql { get; set; }
}
}

13
BBWYB.Server.Business/JD/JDBusiness.cs

@ -17,18 +17,22 @@ namespace BBWYB.Server.Business.JD
private VenderBusiness venderBusiness;
private DingDingBusiness dingDingBusiness;
private TaskSchedulerManager taskSchedulerManager;
private TimeLimitRules timeLimitRules;
public JDBusiness(IFreeSql fsql,
NLogManager nLogManager,
IIdGenerator idGenerator,
RestApiService restApiService,
VenderBusiness venderBusiness,
DingDingBusiness dingDingBusiness,
TaskSchedulerManager taskSchedulerManager) : base(fsql, nLogManager, idGenerator)
TaskSchedulerManager taskSchedulerManager,
TimeLimitRules timeLimitRules) : base(fsql, nLogManager, idGenerator)
{
this.restApiService = restApiService;
this.venderBusiness = venderBusiness;
this.dingDingBusiness = dingDingBusiness;
this.taskSchedulerManager = taskSchedulerManager;
this.timeLimitRules = timeLimitRules;
}
public ApiResponse<IList<JDInStoreOrderDetail>> GetJDInStoreOrderDetailList(string sourceShopName, IList<string> poOrderNos)
@ -39,7 +43,7 @@ namespace BBWYB.Server.Business.JD
try
{
var httpResult = restApiService.SendRequest("https://yunding.qiyue666.com/", "api/PlatformSDK/GetJDInStorePurchaseOrderList", new
var httpResult = restApiService.SendRequest("http://yunding.qiyue666.com/", "api/PlatformSDK/GetJDInStorePurchaseOrderList", new
{
Platform = shop.PlatformId,
shop.AppKey,
@ -71,7 +75,7 @@ namespace BBWYB.Server.Business.JD
var checkTaskList = fsql.Select<InStoreOrderCheckTask>().Where(x => x.IsChecked == false).ToList();
if (checkTaskList.Count() == 0)
return;
orderIds = checkTaskList.Select(x => x.OrderId).ToList();
var timelimitTaskList = fsql.Select<TimeLimitTask>().Where(t => orderIds.Contains(t.OrderId) && t.TaskType == Enums.TimeLimitTaskType.).ToList();
@ -200,7 +204,8 @@ namespace BBWYB.Server.Business.JD
OrderSn = checkTask.OrderSn,
ShopId = checkTask.ShopId,
TaskType = Enums.TimeLimitTaskType.,
ExpirationTime = DateTime.Now.AddDays(1)
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now)
//ExpirationTime = DateTime.Now.AddDays(1)
};
insertTimeLimitTaskList.Add(t);
}

207
BBWYB.Server.Business/Order/OrderBusiness.cs

@ -12,9 +12,7 @@ using Newtonsoft.Json;
using SDKAdapter;
using SDKAdapter.OperationPlatform.Client;
using SDKAdapter.OperationPlatform.Models;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Security.Cryptography;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
@ -27,11 +25,14 @@ namespace BBWYB.Server.Business
private Lazy<QiKuManager> qikuManagerLazy;
private Lazy<OP_PlatformClientFactory> opPlatformClientFactoryLazy;
private Lazy<RestApiService> restApiServiceLazy;
private Lazy<TimeLimitRules> timeLimitRulesLazy;
private OP_PlatformClientFactory opPlatformClientFactory => opPlatformClientFactoryLazy.Value;
private RestApiService restApiService => restApiServiceLazy.Value;
private QiKuManager qikuManager => qikuManagerLazy.Value;
private TimeLimitRules timeLimitRules => timeLimitRulesLazy.Value;
private List<Enums.TimeLimitTaskType?> hgzTaskTypeList;
public OrderBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, IServiceProvider serviceProvider) : base(fsql, nLogManager, idGenerator)
@ -39,7 +40,7 @@ namespace BBWYB.Server.Business
qikuManagerLazy = new Lazy<QiKuManager>(() => serviceProvider.GetService<QiKuManager>());
opPlatformClientFactoryLazy = new Lazy<OP_PlatformClientFactory>(() => serviceProvider.GetService<OP_PlatformClientFactory>());
restApiServiceLazy = new Lazy<RestApiService>(() => serviceProvider.GetService<RestApiService>());
timeLimitRulesLazy = new Lazy<TimeLimitRules>(() => serviceProvider.GetService<TimeLimitRules>());
waitConfigStateList = new List<Enums.PackConfigState?>() { Enums.PackConfigState., Enums.PackConfigState. };
hgzTaskTypeList = new List<Enums.TimeLimitTaskType?>()
@ -60,6 +61,14 @@ namespace BBWYB.Server.Business
select = select.Where((o, ocs, oct) => o.OrderSn == request.OrderSn);
else
{
if (request.OrderState == Enums.OrderState.)
{
var childSelect = fsql.Select<OrderSku>().As("osku1")
.Where(osku1 => osku1.IsNeedOptimization == 1);
select = select.WhereIf(request.IsNeedOptimization == 1, (o, ocs, oct) => childSelect.Where(osku1 => osku1.OrderId == o.Id).Any())
.WhereIf(request.IsNeedOptimization != 1, (o, ocs, oct) => !childSelect.Where(osku1 => osku1.OrderId == o.Id).Any());
}
if (!string.IsNullOrEmpty(request.Sku) ||
!string.IsNullOrEmpty(request.SourceSku) ||
!string.IsNullOrEmpty(request.ProductId) ||
@ -71,9 +80,10 @@ namespace BBWYB.Server.Business
.WhereIf(!string.IsNullOrEmpty(request.ProductId), osku => osku.ProductId == request.ProductId)
.WhereIf(request.IsWaitConfig && request.IsOnlyDisplayPackConfigEditState != 1, osku => waitConfigStateList.Contains(osku.PackConfigState) || osku.PackConfigState == null)
.WhereIf(request.IsWaitConfig && request.IsOnlyDisplayPackConfigEditState == 1, osku => osku.PackConfigState == Enums.PackConfigState.);
select = select.WhereIf(request.IsWaitConfig, (o, ocs, oct) => o.OrderState != Enums.OrderState.)
.WhereIf(request.IsWaitConfig, (o, ocs, oct) => o.IntoStoreType == Enums.IntoStoreType.)
.WhereIf(request.IsWaitConfig, (o, ocs, oct) => o.IsPurchased == true)
select = select.WhereIf(request.IsWaitConfig, (o, ocs, oct) => o.OrderState != Enums.OrderState. &&
o.OrderState != Enums.OrderState. &&
o.IntoStoreType == Enums.IntoStoreType. &&
o.IsPurchased == true)
.Where((o, ocs, oct) => childSelect.Where(osku => osku.OrderId == o.Id).Any());
if (request.IsWaitConfig && request.IsOnlyDisplayCerConfigTimeOut == 1)
@ -220,6 +230,7 @@ namespace BBWYB.Server.Business
var orderList = orderSourceList.Map<IList<OrderResponse>>();
var orderIdList = orderList.Select(o => o.Id).ToList();
if (orderList.Count() > 0)
{
#region 查询关联信息
@ -364,6 +375,12 @@ namespace BBWYB.Server.Business
var orderTimeLimitTaskList = fsql.Select<TimeLimitTask>().Where(t => orderIdList.Contains(t.OrderId))
.ToList<TimeLimitTaskResponse>();
foreach (var task in orderTimeLimitTaskList)
{
if (task.CompletionTime == null)
task.RemainingTime = timeLimitRules.CalculateLessTimeForWorkHour(task.ExpirationTime.Value);
}
foreach (var order in orderList)
{
foreach (var orderSku in order.ItemList)
@ -391,6 +408,12 @@ namespace BBWYB.Server.Business
t.TaskType == Enums.TimeLimitTaskType.);
#endregion
#region 待议价任务
orderSku.OptimizationTimeLimitTask = orderTimeLimitTaskList.FirstOrDefault(t => t.OrderId == order.Id &&
t.SkuId == orderSku.SkuId &&
t.TaskType == Enums.TimeLimitTaskType.);
#endregion
#region 判断sku的发货状态
var purchaseOrder = order.OrderPurchaseInfoList.FirstOrDefault(opi => opi.OrderId == order.Id && opi.BelongSkuIds.Contains(orderSku.SkuId));
if (purchaseOrder != null)
@ -433,7 +456,35 @@ namespace BBWYB.Server.Business
#endregion
#region SKU优化历史
if (request.IsNeedOptimization == 1 && request.OrderState == Enums.OrderState.)
{
var orderSkuIdList = orderSkuList.Where(osku => osku.IsNeedOptimization == 1).Select(osku => osku.SkuId).Distinct().ToList();
var skuOptimizationHistoryList = fsql.Select<SkuOptimizationHistory>()
.Where(x => x.ShopId == request.ShopId && orderSkuIdList.Contains(x.SkuId))
.OrderByDescending(x => x.CreateTime)
.ToList<SkuOptimizationHistoryResponse>();
if (skuOptimizationHistoryList.Count() > 0)
{
foreach (var orderSku in orderSkuList)
{
orderSku.OptimizationHistoryList = skuOptimizationHistoryList.Where(x => x.SkuId == orderSku.SkuId).ToList();
}
}
foreach (var order in orderList)
{
for (var i = 0; i < order.ItemList.Count(); i++)
{
if (order.ItemList[i].IsNeedOptimization != 1)
{
order.ItemList.RemoveAt(i);
i--;
}
}
}
}
#endregion
}
return new OrderListResponse()
{
@ -525,6 +576,12 @@ namespace BBWYB.Server.Business
public void CancelOrder(CancelOrderRequest request, string mdsToken)
{
var order = fsql.Select<Order>(request.OrderId).ToOne();
if (order == null)
throw new BusinessException("订单不存在");
if (order.OrderState == Enums.OrderState.)
return;
try
{
opPlatformClientFactory.GetClient((AdapterEnums.PlatformType)request.Platform).CancelOrder(new OP_CancelOrderRequest()
@ -543,15 +600,38 @@ namespace BBWYB.Server.Business
throw new BusinessException(ex.Message);
}
var orderSkus = fsql.Select<OrderSku>().Where(osku => osku.OrderId == request.OrderId).ToList();
IList<IUpdate<SpuTotalSaleInfo>> updateSpuTotalSaleInfoList = new List<IUpdate<SpuTotalSaleInfo>>();
IList<IUpdate<SkuTotalSaleInfo>> updateSkuTotalSaleInfoList = new List<IUpdate<SkuTotalSaleInfo>>();
var skuGroupsByProductId = orderSkus.GroupBy(osku => osku.ProductId);
foreach (var group in skuGroupsByProductId)
{
var totalItemCount = group.Sum(osku => osku.ItemTotal ?? 0);
foreach (var osku in group)
{
var updateSku = fsql.Update<SkuTotalSaleInfo>(osku.SkuId).Set(s => s.ItemCount - osku.ItemTotal);
updateSkuTotalSaleInfoList.Add(updateSku);
}
var updateSpu = fsql.Update<SpuTotalSaleInfo>(group.Key).Set(s => s.ItemCount - totalItemCount);
updateSpuTotalSaleInfoList.Add(updateSpu);
}
fsql.Transaction(() =>
{
fsql.Update<Order>(request.OrderId).Set(o => o.OrderState, Enums.OrderState.).ExecuteAffrows();
fsql.Delete<TimeLimitTask>().Where(t => t.OrderId == request.OrderId).ExecuteAffrows();
foreach (var update in updateSkuTotalSaleInfoList)
update.ExecuteAffrows();
foreach (var update in updateSpuTotalSaleInfoList)
update.ExecuteAffrows();
});
try
{
restApiService.SendRequest("https://bbwy.qiyue666.com", "api/BatchPurchase/UpdatePurchaseOrderState", new
restApiService.SendRequest("http://bbwytest.qiyue666.com", "api/BatchPurchase/UpdatePurchaseOrderState", new
{
OrderId = request.OrderId,
PurchaseOrderState = Enums.OrderState.
@ -562,14 +642,6 @@ namespace BBWYB.Server.Business
}
//var sql = $"update purchaseorderv2 set OrderState=6 where Id='{request.OrderId}'";
////取消C端采购单
//restApiService.SendRequest("https://bbwy.qiyue666.com",
// "/Api/Sql/ExecuteNonQuery",
// new { sql = sql.AESEncrypt() },
// new Dictionary<string, string>() { { "Authorization", $"Bearer {mdsToken}" } },
// HttpMethod.Post);
try
{
//取消齐库的任务
@ -590,14 +662,17 @@ namespace BBWYB.Server.Business
public void EditPrice(OP_EditPriceRequest request)
{
var client = opPlatformClientFactory.GetClient(request.Platform);
client.EditPrice(new OP_EditPriceRequest()
lock ($"editprice_{request.OrderId}")
{
AppKey = request.AppKey,
AppSecret = request.AppSecret,
AppToken = request.AppToken,
OrderId = request.OrderId,
EditItems = request.EditItems
});
client.EditPrice(new OP_EditPriceRequest()
{
AppKey = request.AppKey,
AppSecret = request.AppSecret,
AppToken = request.AppToken,
OrderId = request.OrderId,
EditItems = request.EditItems
});
}
var orderListResponse = client.GetOrderList(new OP_QueryOrderRequest()
{
@ -688,7 +763,7 @@ namespace BBWYB.Server.Business
});
#region 通知C端
restApiService.SendRequest("https://bbwy.qiyue666.com",
restApiService.SendRequest("http://bbwytest.qiyue666.com",
"/Api/PurchaseOrder/QuanTanEditPriceCallback",
new { orderId = request.OrderId },
null,
@ -716,6 +791,7 @@ namespace BBWYB.Server.Business
public void CheckSku(CheckSkuRequest request)
{
nLogManager.Default().Info($"CheckSku {JsonConvert.SerializeObject(request)}");
var dbOrder = fsql.Select<Order>(request.OrderId).ToOne();
if (dbOrder == null)
throw new BusinessException($"订单{request.OrderId}不存在");
@ -783,7 +859,7 @@ namespace BBWYB.Server.Business
try
{
#if DEBUG
var url = "https://bbwy.qiyue666.com";
var url = "http://bbwytest.qiyue666.com";
#else
var url = "http://172.16.54.105:8090";
#endif
@ -815,27 +891,40 @@ namespace BBWYB.Server.Business
OrderState = g.Key,
OrderCount = g.Count()
});
var childSelect = fsql.Select<OrderSku>().As("osku").Where(osku => waitConfigStateList.Contains(osku.PackConfigState) || osku.PackConfigState == null);
var waitConfigCount = fsql.Select<Order>().Where(o => o.ShopId == shopId)
long waitConfigCount = 0;
{
var childSelect = fsql.Select<OrderSku>().As("osku").Where(osku => waitConfigStateList.Contains(osku.PackConfigState) || osku.PackConfigState == null);
waitConfigCount = fsql.Select<Order>().Where(o => o.ShopId == shopId)
.Where(o => !noOrderStateList.Contains(o.OrderState.Value))
.Where(o => o.IntoStoreType == Enums.IntoStoreType.)
.Where(o => o.IsPurchased == true)
.Where(o => childSelect.Where(osku => osku.OrderId == o.Id).Any())
.Count();
}
int opitimizationCount = 0;
{
var childSelect = fsql.Select<OrderSku>().As("osku").Where(osku => osku.IsNeedOptimization == 1);
opitimizationCount = Convert.ToInt32(fsql.Select<Order>().Where(o => o.ShopId == shopId)
.Where(o => o.OrderState == Enums.OrderState.)
.Where(o => childSelect.Where(osku => osku.OrderId == o.Id).Any())
.Count());
}
return new OrderCountByStateResponse()
{
WaitPayCount = orderCountGroup.FirstOrDefault(o => o.OrderState == Enums.OrderState.)?.OrderCount ?? 0,
WaitPurchaseCount = orderCountGroup.FirstOrDefault(o => o.OrderState == Enums.OrderState. ||
o.OrderState == Enums.OrderState.)?.OrderCount ?? 0,
WaitShipmentCount = orderCountGroup.FirstOrDefault(o => o.OrderState == Enums.OrderState. ||
o.OrderState == Enums.OrderState.)?.OrderCount ?? 0,
WaitReceiveCount = orderCountGroup.FirstOrDefault(o => o.OrderState == Enums.OrderState. ||
o.OrderState == Enums.OrderState.)?.OrderCount ?? 0,
WaitPurchaseCount = orderCountGroup.Where(o => o.OrderState == Enums.OrderState. ||
o.OrderState == Enums.OrderState.).Sum(o => o.OrderCount) - opitimizationCount,
WaitShipmentCount = orderCountGroup.Where(o => o.OrderState == Enums.OrderState. ||
o.OrderState == Enums.OrderState.).Sum(o => o.OrderCount),
WaitReceiveCount = orderCountGroup.Where(o => o.OrderState == Enums.OrderState. ||
o.OrderState == Enums.OrderState.).Sum(o => o.OrderCount),
WaitCheckCount = orderCountGroup.FirstOrDefault(o => o.OrderState == Enums.OrderState.)?.OrderCount ?? 0,
WaitComputationCount = orderCountGroup.FirstOrDefault(o => o.OrderState == Enums.OrderState.)?.OrderCount ?? 0,
WaitConfigCount = waitConfigCount,
OpitimizationCount = opitimizationCount
};
}
@ -852,5 +941,57 @@ namespace BBWYB.Server.Business
{
fsql.Update<Order>(request.OrderId).Set(o => o.IsSpecialOrder, request.IsSpecialOrder).ExecuteAffrows();
}
/// <summary>
/// 完成议价
/// </summary>
/// <param name="request"></param>
public void CompleteOptimization(CompleteOptimizationRequest request)
{
if (!string.IsNullOrEmpty(request.ProductId) || string.IsNullOrEmpty(request.SkuId) || request.ShopId == 0)
throw new BusinessException("参数无效");
var spuSaleInfo = fsql.Select<SpuTotalSaleInfo>(request.ProductId).ToOne();
if (spuSaleInfo == null)
throw new BusinessException($"未找到spu{request.ProductId}销量");
var updateSpuSaleInfo = fsql.Update<SpuTotalSaleInfo>(request.ProductId)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.IsFirstPurchaseCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.FirstPurchaseCompletedItemCount == s.ItemCount)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.IsFirstOptimizationCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.FirstOptimizationCompletedItemCount == s.ItemCount)
.Set(s => s.LastOptimizationItemCount == s.ItemCount)
.Set(s => s.LastOptimizationTime, DateTime.Now)
.Set(s => s.UpdateTime, DateTime.Now);
fsql.Transaction(() =>
{
fsql.Update<OrderSku>().Set(osku => osku.IsOptimizationCompleted, 1)
.Set(osku => osku.IsNeedOptimization, 0)
.Where(osku => osku.ShopId == request.ShopId &&
osku.SkuId == request.SkuId &&
osku.IsNeedOptimization == 1 &&
osku.IsOptimizationCompleted == 0)
.ExecuteAffrows();
fsql.Update<TimeLimitTask>().Set(t => t.CompletionTime, DateTime.Now)
.Set(t => t.IsTimely == (DateTime.Now < t.ExpirationTime ? true : false))
.Where(t => t.ShopId == request.ShopId &&
t.SkuId == request.SkuId &&
t.CompletionTime == null &&
t.TaskType == Enums.TimeLimitTaskType.)
.ExecuteAffrows();
//fsql.Update<SpuTotalSaleInfo>(request.ProductId).Set(s => s.LastOptimizationItemCount == s.ItemCount)
// .Set(s => s.LastOptimizationTime, DateTime.Now)
// .Set(s => s.UpdateTime, DateTime.Now)
// .ExecuteAffrows();
updateSpuSaleInfo?.ExecuteAffrows();
});
}
}
}

342
BBWYB.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs

@ -38,6 +38,7 @@ namespace BBWYB.Server.Business
private Lazy<OP_PlatformClientFactory> opPlatformClientFactoryLazy;
private Lazy<VenderBusiness> venderBusinessLazy;
private Lazy<PurchaseSchemeBusiness> purchaseSchemeBusinessLazy;
private Lazy<TimeLimitRules> timeLimitRulesLazy;
private PP_PlatformClientFactory ppPlatformClientFactory => pplatformClientFactoryLazy.Value;
private TaskSchedulerManager taskSchedulerManager => taskSchedulerManagerLazy.Value;
@ -54,6 +55,8 @@ namespace BBWYB.Server.Business
private PurchaseSchemeBusiness purchaseSchemeBusiness => purchaseSchemeBusinessLazy.Value;
private TimeLimitRules timeLimitRules => timeLimitRulesLazy.Value;
private IList<Enums.OrderState> cantPurchaseOrderStateList;
public PurchaseOrderBusiness(IFreeSql fsql,
@ -73,6 +76,7 @@ namespace BBWYB.Server.Business
opPlatformClientFactoryLazy = new Lazy<OP_PlatformClientFactory>(() => serviceProvider.GetService<OP_PlatformClientFactory>());
venderBusinessLazy = new Lazy<VenderBusiness>(() => serviceProvider.GetService<VenderBusiness>());
purchaseSchemeBusinessLazy = new Lazy<PurchaseSchemeBusiness>(() => serviceProvider.GetService<PurchaseSchemeBusiness>());
timeLimitRulesLazy = new Lazy<TimeLimitRules>(() => serviceProvider.GetService<TimeLimitRules>());
cantPurchaseOrderStateList = new List<Enums.OrderState>()
{
Enums.OrderState.,
@ -266,6 +270,10 @@ namespace BBWYB.Server.Business
throw new BusinessException("缺少采购账号");
if (request.CargoParamGroupList == null || request.CargoParamGroupList.Count() == 0)
throw new BusinessException("缺少下单商品参数");
if (request.CargoParamGroupList.Any(g => string.IsNullOrEmpty(g.PurchaserId)))
throw new BusinessException("缺少采购商Id");
if (request.CargoParamGroupList.GroupBy(c => c.PurchaserId).Any(g => g.Count() > 1))
throw new BusinessException("提交采购商包含重复");
#region 验证同一个批次中,一个订单sku不能同时拥有多个采购方案
IDictionary<string, long> schemeValidationDictionary = new Dictionary<string, long>();
@ -318,8 +326,14 @@ namespace BBWYB.Server.Business
List<OrderPurchaseInfo> insertOrderPurchaseInfos = new List<OrderPurchaseInfo>();
List<OrderPurchaseSkuInfo> insertOrderPurchaseSkuInfos = new List<OrderPurchaseSkuInfo>();
List<IUpdate<PurchaseScheme>> updatePurchaseSchemeList = new List<IUpdate<PurchaseScheme>>();
//List<IUpdate<PurchaseSchemeProductSku>> updatePssList = new List<IUpdate<PurchaseSchemeProductSku>>();
List<OrderPurchaseRelationInfo> insertOrderPurchaseRelationInfoList = new List<OrderPurchaseRelationInfo>();
List<string> updatePurchaseTimeLimitTaskOrderSkuList = new List<string>();
List<IUpdate<Purchaser>> updatePurchaserList = new List<IUpdate<Purchaser>>();
List<SkuHistoryPurchaserRelation> insertSkuHistoryPurchaserRelationList = new List<SkuHistoryPurchaserRelation>();
List<SkuOptimizationHistory> insertSkuOptimizationHistoryList = new List<SkuOptimizationHistory>();
//List<long> updateSkuOptimizationPurhcasementByIdList = new List<long>();
List<QiKuPackTaskSkuPurchaseSchemeIdRequest> notifyQikuPackSchemeParamList = null;
if (dbOrder.IntoStoreType == Enums.IntoStoreType.)
notifyQikuPackSchemeParamList = new List<QiKuPackTaskSkuPurchaseSchemeIdRequest>();
@ -443,7 +457,8 @@ namespace BBWYB.Server.Business
ShopId = request.ShopId,
BelongSkuIds = string.Join(",", belongSkuIdList),
IsEnabled = true,
Remark = !string.IsNullOrEmpty(cargoParamGroup.Remark) ? cargoParamGroup.Remark : request.Remark
Remark = !string.IsNullOrEmpty(cargoParamGroup.Remark) ? cargoParamGroup.Remark : request.Remark,
UpdateTime = DateTime.Now
};
insertOrderPurchaseInfos.Add(orderPurchaserInfo);
#endregion
@ -459,7 +474,10 @@ namespace BBWYB.Server.Business
PurchaseOrderId = purchaseOrderSimpleInfo.OrderId,
PurchaseProductId = purchaseOrderSku.ProductId,
PurchaseSkuId = purchaseOrderSku.SkuId,
ShopId = request.ShopId
ShopId = request.ShopId,
PurchasedPrice = purchaseOrderSku.Price,
PurchasedAmount = purchaseOrderSku.ProductAmount,
PurchasedItemCount = purchaseOrderSku.Quantity
};
insertOrderPurchaseSkuInfos.Add(orderPurchaseSkuInfo);
}
@ -498,24 +516,106 @@ namespace BBWYB.Server.Business
#endregion
}
#region 更新采购方案最近采购价格
#region 更新采购方案/配件
{
var allCargoParamList = new List<CargoParamRequest>();
request.CargoParamGroupList.ForEach(x => allCargoParamList.AddRange(x.CargoParamList));
var cargoParamGroupsBySchemeList = allCargoParamList.GroupBy(c => c.SchemeId);
foreach (var cargoParamGroupsByScheme in cargoParamGroupsBySchemeList)
#region 更新采购方案
{
var cargoParamGroupsBySchemeList = allCargoParamList.GroupBy(c => c.SchemeId);
foreach (var cargoParamGroupsByScheme in cargoParamGroupsBySchemeList)
{
var schemeId = cargoParamGroupsByScheme.Key;
var skuId = cargoParamGroupsByScheme.FirstOrDefault().BelongSkuId;
var skuItemCount = orderSkus.FirstOrDefault(osku => osku.SkuId == skuId)?.ItemTotal ?? 0;
//var lastPurchasePriceCost = cargoParamGroupsByScheme.Sum(cargoParam => createdPurchaseOrderItemList.Where(x => x.SkuId == cargoParam.SkuId)
// .Select(x => x.Price * (cargoParam.PurchaseRatio ?? 1))
// .DefaultIfEmpty(0M)
// .First());
var lastPurchasePriceCost = cargoParamGroupsByScheme.Sum(cargoParam =>
{
return (createdPurchaseOrderItemList.FirstOrDefault(x => x.SkuId == cargoParam.SkuId)?.Price ?? 0) * (cargoParam.PurchaseRatio ?? 1);
});
var purchasedAmount = insertOrderCostDetails.Where(ocd => ocd.SkuId == skuId).Sum(ocd => ocd.SkuAmount);
var update = fsql.Update<PurchaseScheme>(schemeId).Set(ps => ps.LastPurchaseTime, DateTime.Now)
.Set(ps => ps.LastPurchasePriceCost, lastPurchasePriceCost)
.Set(ps => ps.PurchasedCount + 1)
.Set(ps => ps.PurchasedItemCount + skuItemCount)
.Set(ps => ps.PurchasedAmount + purchasedAmount);
updatePurchaseSchemeList.Add(update);
}
}
#endregion
//#region 更新采购配件
//{
// foreach (var cargoParam in allCargoParamList)
// {
// var createOrderItem = createdPurchaseOrderItemList.FirstOrDefault(x => x.SkuId == cargoParam.SkuId);
// if (createOrderItem != null)
// {
// var update = fsql.Update<PurchaseSchemeProductSku>()
// .Set(pss => pss.LastPurchasePriceCost, createOrderItem.Price)
// .Where(pss => pss.PurchaseSkuId == cargoParam.SkuId && pss.SkuPurchaseSchemeId == cargoParam.SchemeId);
// updatePssList.Add(update);
// }
// }
//}
//#endregion
}
#endregion
#region 更新采购商
{
var purchaserIdList = new List<string>();
var purchaserSkuDictionary = new Dictionary<string, List<string>>();
request.CargoParamGroupList.ForEach(x =>
{
var defalutCost = 0M;
var schemeId = cargoParamGroupsByScheme.Key;
purchaserIdList.Add(x.PurchaserId);
purchaserSkuDictionary.Add(x.PurchaserId, x.CargoParamList.Select(c => c.BelongSkuId).Distinct().ToList());
});
//采购商的sku采购关系表
var dbSkuAndPurchaserRelationList = fsql.Select<SkuHistoryPurchaserRelation>()
.Where(spr => purchaserIdList.Contains(spr.PurchaserId) && spr.ShopId == request.ShopId)
.ToList();
var dbPurchaserList = fsql.Select<Purchaser>(purchaserIdList).ToList();
foreach (var purchaserId in purchaserIdList)
{
purchaserSkuDictionary.TryGetValue(purchaserId, out var fromRequestSkuList);
var fromDBSkuList = dbSkuAndPurchaserRelationList.Where(x => x.PurchaserId == purchaserId)
.Select(x => x.SkuId)
.Distinct()
.ToList();
var exceptSkuList = fromRequestSkuList.Except(fromDBSkuList);
var newSkuRelationCount = exceptSkuList.Count();
if (newSkuRelationCount > 0)
{
insertSkuHistoryPurchaserRelationList.AddRange(exceptSkuList.Select(x => new SkuHistoryPurchaserRelation()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
PurchaserId = purchaserId,
ShopId = request.ShopId,
SkuId = x
}));
}
defalutCost = cargoParamGroupsByScheme.Sum(cargoParam => createdPurchaseOrderItemList.Where(x => x.SkuId == cargoParam.SkuId)
.Select(x => x.Price * (cargoParam.PurchaseRatio ?? 1)).DefaultIfEmpty(0M).First());
var update = fsql.Update<PurchaseScheme>(schemeId).Set(ps => ps.LastPurchaseTime, DateTime.Now)
.Set(ps => ps.LastPurchasePriceCost, defalutCost);
updatePurchaseSchemeList.Add(update);
#region 更新采购商归属
var purchaser = dbPurchaserList.FirstOrDefault(p => p.Id == purchaserId);
if (purchaser != null && !string.IsNullOrEmpty(purchaser.BelongBargainTeamId) && purchaser.BelongType == Enums.PurchaserBelongType.)
{
var updatePurchaser = fsql.Update<Purchaser>(purchaserId).Set(p => p.BelongType, Enums.PurchaserBelongType.);
updatePurchaserList.Add(updatePurchaser);
}
#endregion
}
}
#endregion
@ -560,7 +660,9 @@ namespace BBWYB.Server.Business
// totalPurchaseFreight ?? 0M,
// 0M,
// 0M);
orderCost.CalculationOrderCostAndProfit(dbOrder.OrderTotalPrice.Value, orderSkuCostList.Union(insertOrderSkuCostList).ToList());
var allOrderSkuCostList = orderSkuCostList.Union(insertOrderSkuCostList).ToList();
orderCost.CalculationOrderCostAndProfit(dbOrder.OrderTotalPrice.Value, allOrderSkuCostList);
if (!isRepurchase)
@ -590,6 +692,66 @@ namespace BBWYB.Server.Business
}
#endregion
//#region 创建优化历史
//{
// //本批次在线采购的订单sku集合
// var allBelongSkuIdList = request.CargoParamGroupList.SelectMany(cg => cg.CargoParamList.Select(c => c.BelongSkuId)).Distinct().ToList();
// //var optimizationSkuIdList = orderSkus.Where(osku => osku.IsOptimizationCompleted == 1 && allBelongSkuIdList.Contains(osku.SkuId))
// // .Select(osku => osku.SkuId)
// // .ToList();
// var optimizationTaskList = fsql.Select<SkuOptimizationTask>()
// .Where(s => allBelongSkuIdList.Contains(s.SkuId) &&
// s.IsOptimizationCompleted == true &&
// s.IsPurchasementCompleted == false)
// .ToList();
// var optimizationSkuIdList = optimizationTaskList.Select(s => s.SkuId).Distinct().ToList();
// if (optimizationSkuIdList.Count() > 0)
// {
// //优化历史
// var optimizationHistoryList = fsql.Select<SkuOptimizationHistory>()
// .Where(s1 => s1.ShopId == request.ShopId && optimizationSkuIdList.Contains(s1.SkuId))
// .GroupBy(s1 => s1.SkuId)
// .WithTempQuery(g => new { MaxId = g.Max(g.Value.Id) })
// .From<SkuOptimizationHistory>()
// .InnerJoin((s1, s2) => s1.MaxId == s2.Id)
// .ToList((s1, s2) => s2);
// foreach (var optimizationSkuId in optimizationSkuIdList)
// {
// var orderSkuCost = allOrderSkuCostList.FirstOrDefault(x => x.SkuId == optimizationSkuId);
// if (orderSkuCost == null)
// continue;
// var orderSku = orderSkus.FirstOrDefault(x => x.SkuId == optimizationSkuId);
// var lastHistory = optimizationHistoryList.FirstOrDefault(x => x.SkuId == optimizationSkuId);
// var currentPurchasePrice = orderSkuCost.SkuAmount / orderSku.ItemTotal;
// var ratio = (lastHistory?.LastPurchasePrice ?? 0) == 0 ? 0 : 1 - currentPurchasePrice / lastHistory.LastPurchasePrice;
// var newOptimizationHistory = new SkuOptimizationHistory()
// {
// Id = idGenerator.NewLong(),
// CreateTime = DateTime.Now,
// CurrentPurchasePrice = orderSkuCost.SkuAmount / orderSku.ItemTotal,
// ProductId = orderSku.ProductId,
// ShopId = request.ShopId,
// SkuId = optimizationSkuId,
// LastPurchasePrice = lastHistory?.LastPurchasePrice ?? 0,
// OptimizationRatio = ratio,
// TriggerOptimizationReason = orderSku.TriggerOptimizationReason
// };
// insertSkuOptimizationHistoryList.Add(newOptimizationHistory);
// var skuOptimizationTask = optimizationTaskList.FirstOrDefault(x => x.SkuId == optimizationSkuId);
// if (skuOptimizationTask != null)
// updateSkuOptimizationPurhcasementByIdList.Add(skuOptimizationTask.Id);
// }
// }
//}
//#endregion
fsql.Transaction(() =>
{
if (updatePurchaseTimeLimitTaskOrderSkuList.Count() > 0)
@ -610,6 +772,10 @@ namespace BBWYB.Server.Business
fsql.Insert(insertOrderPurchaseSkuInfos).ExecuteAffrows();
if (insertOrderPurchaseRelationInfoList.Count() > 0)
fsql.Insert(insertOrderPurchaseRelationInfoList).ExecuteAffrows();
if (insertSkuHistoryPurchaserRelationList.Count() > 0)
fsql.Insert(insertSkuHistoryPurchaserRelationList).ExecuteAffrows();
if (insertSkuOptimizationHistoryList.Count() > 0)
fsql.Insert(insertSkuOptimizationHistoryList).ExecuteAffrows();
updateOrderCost?.ExecuteAffrows();
insertOrderCost?.ExecuteAffrows();
if (updatePurchaseSchemeList.Count() > 0)
@ -617,6 +783,11 @@ namespace BBWYB.Server.Business
foreach (var update in updatePurchaseSchemeList)
update.ExecuteAffrows();
}
//if (updatePssList.Count() > 0)
//{
// foreach (var update in updatePssList)
// update.ExecuteAffrows();
//}
fsql.Update<Order>(request.OrderId).Set(o => o.OrderState, dbOrder.OrderState)
.SetIf(!string.IsNullOrEmpty(request.Remark), o => o.PurchaseRemark, request.Remark)
.Set(o => o.IsPurchased, true)
@ -628,6 +799,14 @@ namespace BBWYB.Server.Business
foreach (var update in updateOrderSkuCostList)
update.ExecuteAffrows();
}
//if (updateSkuOptimizationPurhcasementByIdList.Count() > 0)
// fsql.Update<SkuOptimizationTask>(updateSkuOptimizationPurhcasementByIdList).Set(s => s.IsPurchasementCompleted, true).ExecuteAffrows();
if (updatePurchaserList.Count() > 0)
{
foreach (var update in updatePurchaserList)
update.ExecuteAffrows();
}
});
//#region 更新采购方案最新价格
@ -937,7 +1116,8 @@ namespace BBWYB.Server.Business
PurchasePlatform = purchaseOrder.PurchasePlatform,
PurchaserId = purchaseOrder.PurchaserId,
PurchaserName = purchaseOrder.PurchaserName,
ShopId = request.ShopId
ShopId = request.ShopId,
UpdateTime = DateTime.Now
};
insertOrderPurchaseInfoList.Add(dbPurchaserOrder);
#endregion
@ -2338,7 +2518,7 @@ namespace BBWYB.Server.Business
{
kuaidi100Company = expressCompanyNameConverter.ConverterToKuaiDi100Company(logisticsInfo.ExpressName);
if (kuaidi100Company == null)
throw new Exception($"无翻译结果");
throw new Exception($"无翻译结果,默认使用专线物流发货,如发现非专线物流请联系技术员,进行调整");
kuaiDi100Manager.SubscribeKuaiDi100(logisticsInfo.WayBillNo, kuaidi100Company.TargetCode, "http://bbwyb.qiyue666.com/api/purchaseorder/kuaidi100publish");
isSubscribeKD100 = true;
}
@ -2363,6 +2543,16 @@ namespace BBWYB.Server.Business
#endregion
if (ex.Message.Contains("无翻译结果"))
{
kuaidi100Company = new LogisticsCompanyRelationship()
{
SecondTargetCode = logisticsInfo.ExpressId,
SourceName = logisticsInfo.ExpressName,
TargetCode = "zhuanxianwuliu",
TargetName = "专线物流"
};
}
else
throw;
}
}
@ -2685,7 +2875,8 @@ namespace BBWYB.Server.Business
OrderSn = order.OrderSn,
ShopId = order.ShopId,
TaskType = Enums.TimeLimitTaskType.,
ExpirationTime = DateTime.Now.AddDays(1)
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now)
//ExpirationTime = DateTime.Now.AddDays(1)
};
insertTimeLimitTaskList.Add(t);
}
@ -2809,7 +3000,8 @@ namespace BBWYB.Server.Business
IList<OP_EditPriceSkuRequest> op_EditPriceSkuRequests = new List<OP_EditPriceSkuRequest>();
IUpdate<OrderPurchaseInfo> updatePurchaseOrder = null;
IUpdate<OrderPurchaseInfo> updatePurchaseOrder = fsql.Update<OrderPurchaseInfo>(orderPurchaseInfo.Id).Set(opi => opi.UpdateTime, DateTime.Now);
List<IUpdate<OrderPurchaseSkuInfo>> updatePurchaserOrderSkuList = new List<IUpdate<OrderPurchaseSkuInfo>>();
IDictionary<string, OP_EditPriceSkuRequest> oskuPriceEditParamDictionary = new Dictionary<string, OP_EditPriceSkuRequest>();
@ -2821,7 +3013,6 @@ namespace BBWYB.Server.Business
{
if (opi.PurchasePlatform != Enums.Platform.)
continue;
var purchaseOrderSimpleInfo = ppclient.QueryOrderDetail(new PP_QueryOrderDetailRequest()
{
AppKey = purchaseAccount.AppKey,
@ -2830,6 +3021,21 @@ namespace BBWYB.Server.Business
OrderId = opi.PurchaseOrderId
});
#region 更新配件下单信息
if (opi.PurchaseOrderId == purchaseOrderId)
{
foreach (var item in purchaseOrderSimpleInfo.ItemList)
{
var update = fsql.Update<OrderPurchaseSkuInfo>().Set(opsi => opsi.PurchasedPrice, item.Price)
.Set(opsi => opsi.PurchasedAmount, item.ProductAmount)
.Set(opsi => opsi.PurchasedItemCount, item.Quantity)
.Where(opsi => opsi.PurchaseOrderId == purchaseOrderId &&
opsi.PurchaseSkuId == item.SkuId);
updatePurchaserOrderSkuList.Add(update);
}
}
#endregion
totalPurchaseProductAmount += purchaseOrderSimpleInfo.ProductAmount;
totalPurchaseFreight += purchaseOrderSimpleInfo.FreightAmount;
var currentPurchaseOrderRelationInfos = dbOrderPurchaseRelationInfos.Where(x => x.PurchaseOrderId == opi.PurchaseOrderId).ToList();
@ -2879,71 +3085,6 @@ namespace BBWYB.Server.Business
}
#endregion
//var purchaseSkuTotalQuantity = purchaseOrderSimpleInfo.ItemList.Sum(x => x.Quantity);
//var belongSkuGroups = currentPurchaseOrderRelationInfos.GroupBy(p => p.BelongSkuId);
//foreach (var belongSkuGroup in belongSkuGroups)
//{
// var belongSkuId = belongSkuGroup.Key;
// var currentOrderSkuCargoParamList = belongSkuGroup.ToList(); //找当前skuId的采购skuId
// var currentOrderSkuProductAmount = 0M; //采购成本
// var currentSkuTotalPurchaseQuantity = currentOrderSkuCargoParamList.Sum(x => x.Quantity); //当前skuId的采购数量总和
// var currentPurchaseFreight = purchaseOrderSimpleInfo.FreightAmount *
// (1.0M * currentSkuTotalPurchaseQuantity / purchaseSkuTotalQuantity); //采购运费
// foreach (var currentOrderSkuCargo in currentOrderSkuCargoParamList)
// {
// var currentPurchaseSkuProductAmount = purchaseOrderSimpleInfo.ItemList.Where(p => p.SkuId == currentOrderSkuCargo.PurchaseSkuId)
// .Sum(p => p.ProductAmount);
// var currentPurchaseSkuTotalQuantity = purchaseOrderSimpleInfo.ItemList.Where(p => p.SkuId == currentOrderSkuCargo.PurchaseSkuId)
// .Sum(p => p.Quantity);
// currentOrderSkuProductAmount += currentPurchaseSkuProductAmount * (1.0M * currentOrderSkuCargo.Quantity.Value / currentPurchaseSkuTotalQuantity);
// }
// #region 订单sku平价
// var orderSku = dbOrderSkus.FirstOrDefault(osku => osku.SkuId == belongSkuId);
// if (isEditOrderPrice)
// {
// if (!oskuPriceEditParamDictionary.TryGetValue(orderSku.SkuId, out OP_EditPriceSkuRequest editSkuPrice))
// {
// editSkuPrice = new OP_EditPriceSkuRequest()
// {
// SkuId = orderSku.SkuId,
// OrderSkuId = orderSku.Id.ToString(),
// InPackAmountPrice = orderSku.InPackAmount ?? 0M
// };
// oskuPriceEditParamDictionary.Add(orderSku.SkuId, editSkuPrice);
// }
// editSkuPrice.Price += currentOrderSkuProductAmount / (orderSku.ItemTotal ?? 1M);
// editSkuPrice.Freight += currentPurchaseFreight ?? 0M;
// //orderSku.Price =
// //orderSku.BuyerPayFreight = currentPurchaseFreight;
// //if (!op_EditPriceSkuRequests.Any(x => x.SkuId == orderSku.SkuId))
// //{
// // op_EditPriceSkuRequests.Add(new OP_EditPriceSkuRequest()
// // {
// // Freight = currentPurchaseFreight ?? 0M,
// // InPackAmountPrice = orderSku.InPackAmount ?? 0M,
// // OrderSkuId = orderSku.Id.ToString(),
// // Price = orderSku.Price ?? 0M,
// // SkuId = orderSku.SkuId
// // });
// // updateOrderSkuList.Add(fsql.Update<OrderSku>(orderSku.Id).Set(osku => osku.Price, orderSku.Price)
// // .Set(osku => osku.BuyerPayFreight, orderSku.BuyerPayFreight));
// //}
// }
// #endregion
// var dbOrderSkuDetail = dbOrderCostDetails.FirstOrDefault(ocd => ocd.SkuId == belongSkuId && ocd.PurchaseOrderId == opi.PurchaseOrderId);
// dbOrderSkuDetail.CalculationOrderCostDetailCostAndProfit(currentOrderSkuProductAmount,
// currentPurchaseFreight ?? 0M,
// dbOrderSkuDetail.OutPackAmount ?? 0M,
// dbOrderSkuDetail.DeliveryExpressFreight ?? 0M);
// updateOrderCostDetailList.Add(fsql.Update<OrderCostDetail>().SetSource(dbOrderSkuDetail));
//}
}
if (isEditOrderPrice)
@ -2970,7 +3111,7 @@ namespace BBWYB.Server.Business
.Set(o => o.OrderSellerPrice, dbOrder.OrderSellerPrice)
.Set(o => o.FreightPrice, dbOrder.FreightPrice);
updatePurchaseOrder = fsql.Update<OrderPurchaseInfo>(orderPurchaseInfo.Id).Set(opi => opi.IsAutoEditOrderPrice, Enums.AutoEditOrderPriceType.);
updatePurchaseOrder = updatePurchaseOrder.Set(opi => opi.IsAutoEditOrderPrice, Enums.AutoEditOrderPriceType.);
#endregion
}
@ -3001,17 +3142,17 @@ namespace BBWYB.Server.Business
#region 订单成本
dbOrderCost.CalculationOrderCostAndProfit(dbOrder.OrderTotalPrice.Value, dbOrderSkuCostList.Union(insertOrderSkuCostList).ToList());
//dbOrderCost.CalculationOrderCostAndProfit(dbOrder.OrderTotalPrice ?? 0M,
// totalPurchaseProductAmount,
// totalPurchaseFreight,
// dbOrderCostDetails.Sum(ocd => ocd.OutPackAmount ?? 0M),
// dbOrderCostDetails.Sum(ocd => ocd.DeliveryExpressFreight ?? 0M));
updateOrderCost = fsql.Update<OrderCost>().SetSource(dbOrderCost);
#endregion
fsql.Transaction(() =>
{
updatePurchaseOrder?.ExecuteAffrows();
if (updatePurchaserOrderSkuList.Count() > 0)
{
foreach (var update in updatePurchaserOrderSkuList)
update.ExecuteAffrows();
}
foreach (var update in updateOrderCostDetailList)
update.ExecuteAffrows();
updateOrderCost?.ExecuteAffrows();
@ -3031,18 +3172,21 @@ namespace BBWYB.Server.Business
{
#region 通知拳探改价
var opclient = opPlatformClientFactory.GetClient(AdapterEnums.PlatformType.);
opclient.EditPrice(new OP_EditPriceRequest()
lock ($"editprice_{dbOrder.Id}")
{
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
OrderId = dbOrder.Id,
EditItems = op_EditPriceSkuRequests
});
opclient.EditPrice(new OP_EditPriceRequest()
{
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
OrderId = dbOrder.Id,
EditItems = op_EditPriceSkuRequests
});
}
#endregion
#region 通知C端改价
restApiService.SendRequest("https://bbwy.qiyue666.com",
restApiService.SendRequest("http://bbwytest.qiyue666.com",
"/Api/PurchaseOrder/QuanTanEditPriceCallback",
new { orderId = dbOrder.Id },
null,
@ -3072,7 +3216,7 @@ namespace BBWYB.Server.Business
try
{
#if DEBUG
var url = "https://bbwy.qiyue666.com";
var url = "http://bbwytest.qiyue666.com";
#else
var url = "http://172.16.54.105:8090";
#endif

162
BBWYB.Server.Business/PurchaseScheme/PurchaseProductAPIService.cs

@ -6,7 +6,9 @@ using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Dto;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json.Linq;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
namespace BBWYB.Server.Business
{
@ -26,12 +28,15 @@ namespace BBWYB.Server.Business
//private ConcurrentDictionary<string, (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)> productChaches;
private IDictionary<string, string> _1688ProductDetailRequestHeader;
private IDictionary<string, string> _1688FactoryCardRequestHeader;
private List<int> _1688ColorPropertyFieldIdList;
private List<string> locationIdList;
private List<string> priceIdList;
private List<string> purchaserNameIdList;
private IList<string> invalidPurchaserNameList;
private IDictionary<string, List<string>> provinceDictionary;
public PurchaseProductAPIService(RestApiService restApiService, IMemoryCache memoryCache)
{
@ -46,8 +51,16 @@ namespace BBWYB.Server.Business
{ "Accept-Encoding","gzip, deflate, br"},
{ "Accept-Language","zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"}
};
_1688FactoryCardRequestHeader = new Dictionary<string, string>()
{
{ "Host","sale.1688.com"},
{ "User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"},
{ "Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"},
{ "Accept-Encoding","gzip, deflate, br"},
{ "Accept-Language","zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"}
};
purchaseProductCacheTimeSpan = TimeSpan.FromDays(1);
_1688ColorPropertyFieldIdList = new List<int>() { 3216, 1627207, 1234, 3151, 7853, 446, 374, 404, 100019516, 3114, 2068 };
_1688ColorPropertyFieldIdList = new List<int>() { 3216, 1627207, 1234, 3151, 7853, 446, 374, 404, 100019516, 3114, 2068, 100018474 };
//jobject["data"]["1081181309101"] != null ?
// jobject["data"]["1081181309101"]["data"]["location"].ToString() :
// jobject["data"]["16347413030323"]["data"]["location"].ToString(),
@ -57,6 +70,23 @@ namespace BBWYB.Server.Business
// jobject["data"]["1081181309582"]["data"]["priceModel"]["currentPrices"][0].Value<decimal>("price") :
// jobject["data"]["16347413030316"]["data"]["priceModel"]["currentPrices"][0].Value<decimal>("price");
priceIdList = new List<string>() { "1081181309582", "1081181309582", "16347413030316", "13772573013151" };
purchaserNameIdList = new List<string>() { "38229149", "38229148", "38229150" };
provinceDictionary = new Dictionary<string, List<string>>()
{
{ "省", new List<string>()
{
"黑龙江","吉林","辽宁","河北","山西","陕西","甘肃","青海","河南","湖北","湖南","山东","江苏","安徽","浙江","江西","福建","台湾","贵州","四川","云南","广东","海南"
}
},
{ "自治区", new List<string>(){ "内蒙古","西藏"}},
{ "回族自治区", new List<string>(){"宁夏"}},
{ "维吾尔自治区", new List<string>(){"新疆"}},
{ "壮族自治区", new List<string>(){"广西"}},
{ "特别行政区",new List<string>(){ "香港","澳门"}},
{ "市",new List<string>(){ "重庆","北京","天津","上海"}}
};
}
public PurchaseSkuBasicInfoResponse GetProductInfo(PurchaseSkuBasicInfoRequest request)
@ -241,10 +271,15 @@ namespace BBWYB.Server.Business
var jsonStr = match.Groups[2].Value;
var jobject = JObject.Parse(jsonStr);
var memberId = jobject["globalData"]?["tempModel"]?["sellerMemberId"]?.ToString();
#region 验证purchaserName
var purchaserName = jobject["globalData"]["tempModel"]["companyName"].ToString();
if (invalidPurchaserNameList.Contains(purchaserName))
var tag = string.Empty;
if (invalidPurchaserNameList.Any(x => purchaserName.Contains(x)))
{
tag = invalidPurchaserNameList.FirstOrDefault(x => purchaserName.Contains(x));
var storeDataMatch = Regex.Match(_1688pageResult.Content, @"(window\.__STORE_DATA=)(.*)(\r*\n*\s*</script>)");
if (storeDataMatch.Success)
{
@ -252,16 +287,37 @@ namespace BBWYB.Server.Business
{
var jsonStr_storeData = storeDataMatch.Groups[2].Value;
var jobject_storeData = JObject.Parse(jsonStr_storeData);
var purchaserName_storeData = jobject_storeData["components"]?["38229149"]?["moduleData"]?["companyName"].ToString();
if (string.IsNullOrEmpty(purchaserName_storeData))
purchaserName_storeData = jobject_storeData["components"]?["38229148"]?["moduleData"]?["companyName"].ToString();
if (string.IsNullOrEmpty(purchaserName_storeData))
purchaserName_storeData = jobject_storeData["components"]?["38229150"]?["moduleData"]?["companyName"].ToString();
if (!string.IsNullOrEmpty(purchaserName_storeData))
purchaserName = purchaserName_storeData;
foreach (var purchaserNodeId in purchaserNameIdList)
{
var purchaserTempName = jobject_storeData["components"]?[purchaserNodeId]?["moduleData"]?["companyName"].ToString();
if (!string.IsNullOrEmpty(purchaserTempName))
{
purchaserName = purchaserTempName;
break;
}
}
}
catch { }
}
if (invalidPurchaserNameList.Any(x => purchaserName.Contains(x)) && !string.IsNullOrEmpty(memberId))
{
//https://sale.1688.com/factory/card.html?memberId=b2b-4204371240a61bf
var _1688FactoryCardResult = restApiService.SendRequest("https://sale.1688.com",
"factory/card.html",
$"memberId={memberId}",
_1688FactoryCardRequestHeader,
HttpMethod.Get,
httpClientName: "gzip");
if (_1688FactoryCardResult.StatusCode == System.Net.HttpStatusCode.OK)
{
var titleMatch = Regex.Match(_1688FactoryCardResult.Content, @"<title>(.*)-(.*)-(.*)</title>");
if (titleMatch.Success)
{
purchaserName = titleMatch.Groups[1].Value;
}
}
}
}
#endregion
@ -271,19 +327,52 @@ namespace BBWYB.Server.Business
if (jobject["data"][locationIdList[i]] != null)
{
location = jobject["data"][locationIdList[i]]["data"]["location"].ToString();
if (string.IsNullOrEmpty(location))
continue;
break;
}
}
if (string.IsNullOrEmpty(location))
{
var jobjectdata = jobject["data"] as JObject;
foreach (var jproperty in jobjectdata.Properties())
{
if (jobjectdata[jproperty.Name].Value<string>("componentType") == "@ali/tdmod-od-pc-attribute-new")
{
location = jobjectdata[jproperty.Name]["data"].FirstOrDefault(x => x.Value<string>("name") == "产地")?.Value<string>("value");
if (!string.IsNullOrEmpty(location))
break;
}
}
if (string.IsNullOrEmpty(location))
{
if (purchaserName.Contains("市") && purchaserName.Contains("区"))
{
location = purchaserName.Substring(0, purchaserName.IndexOf("区") + 1);
}
else if (purchaserName.Contains("市"))
{
location = purchaserName.Substring(0, purchaserName.IndexOf("市") + 1);
}
}
}
location = FormatteLocation(location);
var purchaser = new Purchaser()
{
Id = jobject["globalData"]["tempModel"]["sellerUserId"].ToString(),
Id2 = jobject["globalData"]["tempModel"]["sellerLoginId"]?.ToString(),
Name = purchaserName,
MemberId = jobject["globalData"]?["tempModel"]?["sellerMemberId"]?.ToString(),
MemberId = memberId,
Location = location,
Platform = Enums.Platform.
Platform = Enums.Platform.,
Tag = tag
};
//_1688ColorPropertyFieldIdList.Add(100018474);
var fidJToken = jobject["globalData"]["skuModel"]["skuProps"].FirstOrDefault(j => _1688ColorPropertyFieldIdList.Contains(j.Value<int>("fid")));
if (fidJToken == null)
fidJToken = jobject["globalData"]["skuModel"]["skuProps"].FirstOrDefault(j => j.Value<string>("prop").Contains("颜色"));
@ -345,34 +434,27 @@ namespace BBWYB.Server.Business
}
}
//private (Purchaser purchaser, IList<PurchaseSchemeProductSku> purchaseSchemeProductSkus)? LoadFromQTSpider(Platform platform, string productId, string skuId, string purchaseProductId, PurchaseOrderMode priceMode)
//{
// try
// {
// var response = quanTanProductClient.GetProductInfo(purchaseProductId, qtAppId, qtAppSecret);
// if (response.Status != 200)
// return null;
// return (new Purchaser()
// {
// Id = response.Data.Supplier.VenderId,
// Name = response.Data.Supplier.VerdenName,
// Location = response.Data.Supplier.Location
// }, response.Data.ProductSku.Select(qtsku => new PurchaseSchemeProductSku()
// {
// ProductId = productId,
// SkuId = skuId,
// PurchaseProductId = purchaseProductId,
// Price = qtsku.Price,
// Title = qtsku.Title,
// PurchaseSkuId = qtsku.SkuId,
// PurchaseSkuSpecId = string.Empty,
// Logo = qtsku.Logo
// }).ToList());
// }
// catch
// {
// return null;
// }
//}
private string FormatteLocation(string location)
{
if (string.IsNullOrEmpty(location))
return location;
location = location.Trim().Replace(" ", string.Empty);
foreach (var provincekey in provinceDictionary.Keys)
{
var province = provinceDictionary[provincekey].FirstOrDefault(p => location.StartsWith(p));
if (string.IsNullOrEmpty(province))
continue;
if (location.Contains(provincekey))
return location;
location = location.Replace(province, $"{province}{provincekey}");
if (location.EndsWith(provincekey))
return location;
if (!location.EndsWith("市"))
location = $"{location}市";
}
//Console.WriteLine(location);
return location;
}
}
}

814
BBWYB.Server.Business/PurchaseScheme/PurchaseSchemeBusiness.cs

File diff suppressed because it is too large

263
BBWYB.Server.Business/Purchaser/PurchaserBusiness.cs

@ -0,0 +1,263 @@
using BBWYB.Common.Log;
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Dto;
using FreeSql;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
{
public class PurchaserBusiness : BaseBusiness, IDenpendency
{
private FreeSqlMultiDBManager _freeSqlMultiDBManager;
public PurchaserBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, FreeSqlMultiDBManager freeSqlMultiDBManager) : base(fsql, nLogManager, idGenerator)
{
this._freeSqlMultiDBManager = freeSqlMultiDBManager;
}
public ListResponse<string> QueryPurchaserNameList(string keywords)
{
if (string.IsNullOrEmpty(keywords))
throw new BusinessException("关键字不能为空");
var list = fsql.Select<Purchaser>().Where(p => p.Name.Contains(keywords)).Distinct().ToList(x => x.Name);
return new ListResponse<string> { Items = list, TotalCount = list.Count() };
}
public ListResponse<string> QueryPurchaserLocationList(string keywords)
{
if (string.IsNullOrEmpty(keywords))
throw new BusinessException("关键字不能为空");
var list = fsql.Select<Purchaser>().Where(p => p.Location.Contains(keywords)).Distinct().ToList(x => x.Location);
return new ListResponse<string> { Items = list, TotalCount = list.Count() };
}
public ListResponse<PurchaserResponse> QueryPurchaserList(QueryPurchaserRequest request)
{
//默认ShopId为空
request.ShopId = null;
#region 数据验证
if (request.RecentDayCondition != null) // && request.RecentDayCondition.RecentDay > 0
{
if (request.RecentDayCondition.PurchasedCountComparisonOperator != null)
{
if (request.RecentDayCondition.PurchasedCount == null || (request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator. &&
request.RecentDayCondition.PurchasedCount2 == null))
throw new BusinessException("采购量条件不完整");
}
if (request.RecentDayCondition.PurchasedAmountComparisonOperator != null)
{
if (request.RecentDayCondition.PurchasedAmount == null || (request.RecentDayCondition.PurchasedAmountComparisonOperator == Enums.ComparisonOperator. &&
request.RecentDayCondition.PurchasedAmount2 == null))
throw new BusinessException("采购金额条件不完整");
}
}
#endregion
if (request.PageSize > 20)
request.PageSize = 20;
var select = fsql.Select<Purchaser>()
.WhereIf(!string.IsNullOrEmpty(request.Spu), p => fsql.Select<PurchaseSchemeProduct>()
.Where(psp1 => psp1.PurchaserId == p.Id &&
psp1.ProductId == request.Spu)
.Any())
.WhereIf(!string.IsNullOrEmpty(request.Sku), p => fsql.Select<PurchaseSchemeProduct>()
.Where(psp2 => psp2.PurchaserId == p.Id &&
psp2.SkuId == request.Sku)
.Any())
.WhereIf(request.PurchaserNameList != null &&
request.PurchaserNameList.Count() > 0, p => request.PurchaserNameList.Contains(p.Name))
.WhereIf(request.CategoryIdList != null &&
request.CategoryIdList.Count() > 0, p => fsql.Select<Purchaser_ExtendedInfo_Relation>()
.Where(per => per.PurchaserId == p.Id &&
request.CategoryIdList.Contains(per.ExtendedInfoId.Value)).Any())
.WhereIf(request.LocationList != null && request.LocationList.Count() > 0, p => request.LocationList.Contains(p.Location))
.WhereIf(request.ManagmentMode != null, p => p.ManagmentMode == request.ManagmentMode);
if (request.RecentDayCondition != null) // && request.RecentDayCondition.RecentDay > 0
{
//var recentStartDay = DateTime.Now.Date.AddDays(request.RecentDayCondition.RecentDay.Value * -1);
if (request.RecentDayCondition.PurchasedCountComparisonOperator != null &&
request.RecentDayCondition.PurchasedCount != null &&
request.RecentDayCondition.PurchasedCount != 0)
{
select = select.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedCount != null && p.Recent90dPurchasedCount == request.RecentDayCondition.PurchasedCount)
.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedCount != null && p.Recent90dPurchasedCount <= request.RecentDayCondition.PurchasedCount)
.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedCount != null && p.Recent90dPurchasedCount >= request.RecentDayCondition.PurchasedCount)
.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedCount != null && p.Recent90dPurchasedCount >= request.RecentDayCondition.PurchasedCount &&
p.Recent90dPurchasedCount <= request.RecentDayCondition.PurchasedCount2);
}
if (request.RecentDayCondition.PurchasedAmountComparisonOperator != null &&
request.RecentDayCondition.PurchasedAmount != null &&
request.RecentDayCondition.PurchasedAmount != 0)
{
select = select.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedAmount != null && p.Recent90dPurchasedAmount == request.RecentDayCondition.PurchasedAmount)
.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedAmount != null && p.Recent90dPurchasedAmount <= request.RecentDayCondition.PurchasedAmount)
.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedAmount != null && p.Recent90dPurchasedAmount >= request.RecentDayCondition.PurchasedAmount)
.WhereIf(request.RecentDayCondition.PurchasedCountComparisonOperator == Enums.ComparisonOperator.,
p => p.Recent90dPurchasedAmount != null && p.Recent90dPurchasedAmount >= request.RecentDayCondition.PurchasedAmount &&
p.Recent90dPurchasedAmount <= request.RecentDayCondition.PurchasedAmount2);
}
}
select = select.Page(request.PageIndex, request.PageSize)
.OrderByPropertyNameIf(!string.IsNullOrEmpty(request.SortColumn), request.SortColumn, request.SortType == 0);
var sql = select.ToSql();
var purchaserList = select.Count(out var count).ToList<PurchaserResponse>();
if (purchaserList.Count() > 0)
{
var purchaserIdList = purchaserList.Select(p => p.Id).ToList();
#region 查询标签/主营类目
var purchaserExtendInfoList = fsql.Select<PurchaserExtendedInfo, Purchaser_ExtendedInfo_Relation>()
.InnerJoin((pei, per) => pei.Id == per.ExtendedInfoId)
.Where((pei, per) => purchaserIdList.Contains(per.PurchaserId))
.ToList((pei, per) => new
{
pei.Id,
pei.Name,
pei.Type,
per.PurchaserId,
pei.ExtendInfo
});
#endregion
#region 最近采购的店铺商品
var recentStartDay = DateTime.Now.Date.AddDays(-90);
var recentEndDay = DateTime.Now.Date;
var bePurchasedProductSkuList = fsql.Select<OrderPurchaseInfo, OrderPurchaseRelationInfo, Order, ProductSku>()
.InnerJoin((opi, opri, o, ps) => opi.OrderId == o.Id)
.InnerJoin((opi, opri, o, ps) => opri.PurchaseOrderId == opi.PurchaseOrderId)
.InnerJoin((opi, opri, o, ps) => opri.BelongSkuId == ps.Id)
.WhereIf(request.ShopId != null && request.ShopId > 0, (opi, opri, o, ps) => o.ShopId == request.ShopId)
.Where((opi, opri, o, ps) => o.OrderState != Enums.OrderState. &&
opi.IsEnabled == true &&
opi.CreateTime >= recentStartDay &&
opi.CreateTime < recentEndDay &&
purchaserIdList.Contains(opi.PurchaserId))
.GroupBy((opi, opri, o, ps) => new
{
ps.Id,
opi.PurchaserId,
ps.Logo,
ps.SkuName,
opri.SourceSkuId
})
.ToList(g => new
{
g.Key.Id,
g.Key.PurchaserId,
g.Key.Logo,
g.Key.SkuName,
g.Key.SourceSkuId,
MaxPurchasedTime = g.Max(g.Value.Item1.CreateTime)
});
var belongSkuIdList = bePurchasedProductSkuList.Select(x => x.SourceSkuId).Distinct().ToList();
var belongSkuList = _freeSqlMultiDBManager.BBWYCfsql.Select<BBWYB.Server.Model.Db.BBWY.ProductSku>(belongSkuIdList).ToList(ps => new { ps.Id, ps.Logo });
#endregion
foreach (var purchaser in purchaserList)
{
#region 主营类目/标签
var currentExtendInfoList = purchaserExtendInfoList.Where(x => x.PurchaserId == purchaser.Id).ToList();
purchaser.CategoryList = currentExtendInfoList.Where(x => x.Type == Enums.PurchaserBasicInfoType.)
.Select(x => new PurchaserExtendedInfoResponse()
{
Id = x.Id,
Name = x.Name,
Type = x.Type,
ExtendInfo = x.ExtendInfo
}).ToList();
purchaser.TagList = currentExtendInfoList.Where(x => x.Type == Enums.PurchaserBasicInfoType.)
.Select(x => new PurchaserExtendedInfoResponse()
{
Id = x.Id,
Name = x.Name,
Type = x.Type,
ExtendInfo = x.ExtendInfo
}).ToList();
#endregion
#region 最近采购店铺商品
purchaser.Recent30dProductSku = bePurchasedProductSkuList.Where(x => x.PurchaserId == purchaser.Id)
.OrderByDescending(x => x.MaxPurchasedTime)
.Take(10)
.Select(x =>
{
var belongSku = belongSkuList.FirstOrDefault(b => b.Id == x.SourceSkuId);
return new RecentPurchasedSkuResponse()
{
Id = x.Id,
Logo = belongSku?.Logo ?? x.Logo,
SkuName = x.SkuName,
BelongSku = x.SourceSkuId,
MaxPurchasedTime = x.MaxPurchasedTime
};
}).ToList();
#endregion
}
}
return new ListResponse<PurchaserResponse>()
{
Items = purchaserList,
TotalCount = count
};
}
public ListResponse<PurchaserExtendedInfoResponse> QueryPurchaserCategoryList(QueryPurchaserExtendedRequest request)
{
var list = fsql.Select<PurchaserExtendedInfo>()
.WhereIf(request.Type != null, x => x.Type == request.Type)
.WhereIf(!string.IsNullOrEmpty(request.Keywords), x => x.Name.Contains(request.Keywords))
.Count(out var count)
.ToList<PurchaserExtendedInfoResponse>();
return new ListResponse<PurchaserExtendedInfoResponse> { Items = list, TotalCount = count };
}
public void EditPurchaserExtendedInfo(EditPurchaserExtendedInfoRequest request)
{
var insertRelationList = new List<Purchaser_ExtendedInfo_Relation>();
insertRelationList.AddRange(request.CategoryIdList.Select(x => new Purchaser_ExtendedInfo_Relation()
{
Id = idGenerator.NewLong(),
PurchaserId = request.PurchaserId,
ExtendedType = Enums.PurchaserBasicInfoType.,
ExtendedInfoId = x
}));
insertRelationList.AddRange(request.TagIdList.Select(x => new Purchaser_ExtendedInfo_Relation()
{
Id = idGenerator.NewLong(),
PurchaserId = request.PurchaserId,
ExtendedType = Enums.PurchaserBasicInfoType.,
ExtendedInfoId = x
}));
fsql.Transaction(() =>
{
fsql.Delete<Purchaser_ExtendedInfo_Relation>().Where(r => r.PurchaserId == request.PurchaserId).ExecuteAffrows();
fsql.Update<Purchaser>(request.PurchaserId).Set(p => p.ManagmentMode, request.ManagmentMode).ExecuteAffrows();
if (insertRelationList.Count() > 0)
fsql.Insert(insertRelationList).ExecuteAffrows();
});
}
}
}

34
BBWYB.Server.Business/QiKuManager.cs

@ -19,10 +19,14 @@ namespace BBWYB.Server.Business
private Lazy<DingDingBusiness> dingDingBusinessLazy;
private Lazy<VenderBusiness> venderBusinessLazy;
private Lazy<TimeLimitRules> timeLimitRulesLazy;
private DingDingBusiness dingDingBusiness => dingDingBusinessLazy.Value;
private VenderBusiness venderBusiness => venderBusinessLazy.Value;
private TimeLimitRules timeLimitRules => timeLimitRulesLazy.Value;
public QiKuManager(RestApiService restApiService, IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, IServiceProvider serviceProvider) : base(fsql, nLogManager, idGenerator)
{
this.restApiService = restApiService;
@ -33,6 +37,7 @@ namespace BBWYB.Server.Business
};
this.dingDingBusinessLazy = new Lazy<DingDingBusiness>(() => serviceProvider.GetService<DingDingBusiness>());
this.venderBusinessLazy = new Lazy<VenderBusiness>(() => serviceProvider.GetService<VenderBusiness>());
this.timeLimitRulesLazy = new Lazy<TimeLimitRules>(() => serviceProvider.GetService<TimeLimitRules>());
}
public void PublishQikuReceiveInfo(string orderId,
@ -103,14 +108,14 @@ namespace BBWYB.Server.Business
}
//推送齐库
var publishResult = restApiService.SendRequest("http://qiku.qiyue666.com",
"/Api/PackPurchaseTask/UpdateAvailabilityState",
new
{
availability = isSignAll ? 0 : 1,
orderId = osku.OrderId,
skuId = osku.BelongSkuId
}, null, HttpMethod.Post);
var publishResult = restApiService.SendRequest("http://qiku.qiyue666.com",
"/Api/PackPurchaseTask/UpdateAvailabilityState",
new
{
availability = isSignAll ? 0 : 1,
orderId = osku.OrderId,
skuId = osku.BelongSkuId
}, null, HttpMethod.Post);
if (publishResult.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(publishResult.Content);
}
@ -179,7 +184,7 @@ namespace BBWYB.Server.Business
OrderSn = order.OrderSn,
ShopId = order.ShopId,
TaskType = Enums.TimeLimitTaskType.,
ExpirationTime = DateTime.Now.AddDays(1),
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now) //DateTime.Now.AddDays(1),
};
insertTimeLimitTaskList.Add(t);
}
@ -256,12 +261,13 @@ namespace BBWYB.Server.Business
SkuId = orderSku.SkuId,
OrderSn = order.OrderSn,
ShopId = order.ShopId,
TaskType = Enums.TimeLimitTaskType.
TaskType = Enums.TimeLimitTaskType.,
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now) //DateTime.Now.AddHours(2)
};
if (DateTime.Now.Hour < 16)
t.ExpirationTime = DateTime.Now.AddHours(2);
else
t.ExpirationTime = DateTime.Now.Date.AddDays(1).AddHours(13);
//if (DateTime.Now.Hour < 16)
// t.ExpirationTime = DateTime.Now.AddHours(2);
//else
// t.ExpirationTime = DateTime.Now.Date.AddDays(1).AddHours(13);
insertTimeLimitTask = fsql.Insert(t);
#region 发送钉钉通知

954
BBWYB.Server.Business/SkuOptimization/OptimizationBusiness.cs

@ -0,0 +1,954 @@
using BBWYB.Common.Extensions;
using BBWYB.Common.Log;
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Db.BBWY;
using BBWYB.Server.Model.Db.SpuOptimization;
using BBWYB.Server.Model.Dto;
using FreeSql;
using Newtonsoft.Json;
using System.Numerics;
using System.Text.RegularExpressions;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
{
public class OptimizationBusiness : BaseBusiness, IDenpendency
{
private FreeSqlMultiDBManager fsqlManager;
private VenderBusiness venderBusiness;
private TimeLimitRules timeLimitRules;
private UserBusiness userBusiness;
private PurchaseSchemeBusiness purchaseSchemeBusiness;
public OptimizationBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, FreeSqlMultiDBManager fsqlManager, VenderBusiness venderBusiness, TimeLimitRules timeLimitRules, UserBusiness userBusiness, PurchaseSchemeBusiness purchaseSchemeBusiness) : base(fsql, nLogManager, idGenerator)
{
this.fsqlManager = fsqlManager;
this.venderBusiness = venderBusiness;
this.timeLimitRules = timeLimitRules;
this.userBusiness = userBusiness;
this.purchaseSchemeBusiness = purchaseSchemeBusiness;
}
public Enums.TriggerOptimizationReason? GetOptimizationReason(SpuTotalSaleInfo s)
{
if (s.IsFirstPurchaseCompleted == false)
return Enums.TriggerOptimizationReason.;
if (s.IsFirstPurchaseCompleted == true &&
s.IsFirstOptimizationCompleted == false)
{
if (s.ItemCount - s.FirstPurchaseCompletedItemCount >= 20)
return Enums.TriggerOptimizationReason.;
if (s.LastOptimizationTime != null &&
(DateTime.Now.Date - s.LastOptimizationTime.Value.Date).TotalDays > 30)
return Enums.TriggerOptimizationReason.;
}
if (s.IsFirstOptimizationCompleted == true)
{
if (s.LastOptimizationItemCount != 0 && s.ItemCount * 1.0 / s.LastOptimizationItemCount >= 2)
return Enums.TriggerOptimizationReason.;
if (s.LastOptimizationTime != null &&
(DateTime.Now.Date - s.LastOptimizationTime.Value.Date).TotalDays > 30)
return Enums.TriggerOptimizationReason.;
}
return null;
}
/// <summary>
/// 良库预警
/// </summary>
/// <param name="request"></param>
/// <exception cref="BusinessException"></exception>
public void LKInventoryAlertNotification(BatchLKInventoryAlertRequest request)
{
nLogManager.Default().Info($"LKInventoryAlertNotification {JsonConvert.SerializeObject(request)}");
#region 确定JDSKU对应的拳探SKU和拳探SPU
var jdSkuIdList = request.Items.Select(x => x.Sku).Distinct().ToList();
var jdqtskuList = fsqlManager.BBWYCfsql.Select<PurchaseOrderSku>()
.Where(ps1 => ps1.ShopId == request.ShopId && jdSkuIdList.Contains(ps1.SkuId))
.GroupBy(ps1 => ps1.SkuId)
.WithTempQuery(g => new { MaxId = g.Max(g.Value.Id) })
.From<PurchaseOrderSku>()
.InnerJoin((ps1, ps2) => ps1.MaxId == ps2.Id)
.ToList((ps1, ps2) => ps2);
var qtSkuIdList = jdqtskuList.Select(x => x.PurchaseSkuIds).Distinct().ToList();
var productSkuList = fsql.Select<Model.Db.ProductSku>(qtSkuIdList).ToList();
if (productSkuList.Count() == 0)
return;
var shopId = productSkuList.FirstOrDefault()?.ShopId;
var productIdList = productSkuList.Select(ps => ps.ProductId).Distinct().ToList();
var productList = fsql.Select<Product>(productIdList).ToList();
var dbSpuTotalInfoList = fsql.Select<SpuTotalSaleInfo>().Where(spi => productIdList.Contains(spi.ProductId)).ToList();
#endregion
//查询已存在未结束的优化任务
var dbSpuOptimizationTaskList = fsql.Select<SpuOptimizationTask>()
.Where(t => t.ShopId == shopId &&
t.IsOptimizationCompleted == false &&
productIdList.Contains(t.ProductId))
.ToList();
//优化历史
var dbSpuOptimizationHistoryList = fsql.Select<SpuOptimizationTask>()
.Where(s1 => productIdList.Contains(s1.ProductId) && s1.IsOptimizationCompleted == true)
.GroupBy(s1 => s1.ProductId)
.WithTempQuery(g => new { MaxId = g.Max(g.Value.Id) })
.From<SpuOptimizationTask>()
.InnerJoin((s1, s2) => s1.MaxId == s2.Id)
.ToList((s1, s2) => s2);
#region DB Operation
List<SpuOptimizationTask> insertSpuOptimizationTaskList = new List<SpuOptimizationTask>();
List<SkuOptimizationTask> insertSkuOptimizationTaskList = new List<SkuOptimizationTask>();
List<SpuOptimizationBargainTeamTask> insertSpuOptimizationBargainTeamTaskList = new List<SpuOptimizationBargainTeamTask>();
List<SpuOptimizationCompetitiveTenderTask> insertSpuOptimizationCompetitiveTenderTaskList = new List<SpuOptimizationCompetitiveTenderTask>();
//List<SpuOptimizationPurchaserCompetitiveTenderTask> insertSpuOptimizationPurchaserCompetitiveTenderTaskList = new List<SpuOptimizationPurchaserCompetitiveTenderTask>();
List<TimeLimitTask> insertTimeLimitTaskList = new List<TimeLimitTask>();
#endregion
var belongShop = venderBusiness.GetShopList(request.ShopId).FirstOrDefault();
if (belongShop == null)
throw new BusinessException("店铺不存在");
var bargainTeamList = venderBusiness.GetYiJiaGroup(); //获取议价组
var bargainTeamIdList = bargainTeamList.Select(t => t.Id).ToList();
var waitToCompetitiveTenderSchemeList = fsql.Select<PurchaseScheme>()
.Where(ps => bargainTeamIdList.Contains(ps.BelongBargainTeamId) &&
productIdList.Contains(ps.ProductId))
.ToList(); //需要参与竞标采购方案
var waitToCompetitiveTenderSchemeIdList = waitToCompetitiveTenderSchemeList.Select(ps => ps.Id).ToList();
var waitToCompetitiveTenderSchemePurchaserList = fsql.Select<PurchaseSchemeProduct>()
.Where(psp => waitToCompetitiveTenderSchemeIdList.Contains(psp.SkuPurchaseSchemeId))
.GroupBy(psp => new { psp.SkuPurchaseSchemeId, psp.PurchaserId })
.ToList(g => new { g.Key.SkuPurchaseSchemeId, g.Key.PurchaserId }); //需要参与竞标的采购商
foreach (var productId in productIdList)
{
#region 验证
if (dbSpuOptimizationTaskList.Any(s => s.ProductId == productId)) //过滤未结束的spu任务
continue;
var spuTotalInfo = dbSpuTotalInfoList.FirstOrDefault(psi => psi.ProductId == productId); //spu销量
if (spuTotalInfo == null)
continue;
var reason = GetOptimizationReason(spuTotalInfo); //过滤不需要优化的spu
if (reason == null)
continue;
#endregion
var skuOptimizationHistory = dbSpuOptimizationHistoryList.FirstOrDefault(h => h.ProductId == productId); //优化历史
#region qtsku - jdsku 关系匹配
var currentProductSkuList = productSkuList.Where(ps => ps.ProductId == productId &&
jdqtskuList.Any(x => x.PurchaseSkuIds == ps.Id)).ToList();
if (currentProductSkuList.Count() == 0)
continue;
//拳探sku-京东sku下单关系映射表
var mappingQT_JDSKUDictionary = new Dictionary<string, string>();
foreach (var ps in currentProductSkuList)
{
var jdsku = jdqtskuList.FirstOrDefault(x => x.PurchaseSkuIds == ps.Id)?.SkuId;
if (string.IsNullOrEmpty(jdsku))
continue;
if (!mappingQT_JDSKUDictionary.ContainsKey(ps.Id))
mappingQT_JDSKUDictionary.TryAdd(ps.Id, jdsku);
}
var jdskus = mappingQT_JDSKUDictionary.Values.ToList();
var qtskus = mappingQT_JDSKUDictionary.Keys.ToList();
#endregion
#region 读取JDSKU预估金额
var jdskuRecentCostList = fsqlManager.BBWYCfsql.Select<SkuRecentCost>(jdskus).ToList();
#endregion
#region 创建SPU优化任务
var spuOptimizationTask = new SpuOptimizationTask()
{
Id = idGenerator.NewLong(),
BelongShopId = long.Parse(belongShop.ShopId),
BelongShopName = belongShop.ShopName,
CompletionTime = null,
CreateTime = DateTime.Now,
IsOptimizationCompleted = false,
LastOptimizationTime = null,
ProductId = productId,
ShopId = shopId,
ProductTitle = productList.FirstOrDefault(p => p.Id == productId)?.ProductName,
TriggerOptimizationReason = reason,
PreSkuCount = jdskus.Count(),
PreItemCount = 0,
PrePurchaseAmount = 0M
};
insertSpuOptimizationTaskList.Add(spuOptimizationTask);
#endregion
#region 创建SKU优化任务
foreach (var sku in mappingQT_JDSKUDictionary.Keys)
{
mappingQT_JDSKUDictionary.TryGetValue(sku, out string jdSkuId);
var requestSkuItem = request.Items.FirstOrDefault(x => x.Sku == jdSkuId);
if (requestSkuItem == null)
continue;
var preItemCount = requestSkuItem.PreItemCount;
var prePurchaseAmount = 0M;
if (!string.IsNullOrEmpty(jdSkuId))
{
var jdSkuRecentCost = jdskuRecentCostList.FirstOrDefault(x => x.SkuId == jdSkuId);
if (jdSkuRecentCost != null)
{
prePurchaseAmount = (jdSkuRecentCost.SingleSkuAmount ?? 0M +
jdSkuRecentCost.SingleFirstFreight ?? 0M +
jdSkuRecentCost.SingleFreight ?? 0M +
jdSkuRecentCost.SingleDeliveryFreight ?? 0M +
jdSkuRecentCost.SingleConsumableAmount ?? 0M +
jdSkuRecentCost.SingleInStorageAmount ?? 0M +
jdSkuRecentCost.SingleOutStorageAmount ?? 0M +
jdSkuRecentCost.SinglePackagingLaborAmount ?? 0M +
jdSkuRecentCost.SingleOperationAmount ?? 0M) * preItemCount;
}
}
var skuOptimizationTask = new SkuOptimizationTask()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
JDSkuId = jdSkuId,
PreItemCount = preItemCount,
SkuId = sku,
SpuOptimizationTaskId = spuOptimizationTask.Id,
PrePurchaseAmount = prePurchaseAmount
};
insertSkuOptimizationTaskList.Add(skuOptimizationTask);
//累计spu优化任务信息
spuOptimizationTask.PreItemCount += preItemCount;
spuOptimizationTask.PrePurchaseAmount += prePurchaseAmount;
}
#endregion
#region 创建SPU优化议价组任务
foreach (var department in bargainTeamList)
{
var spuOptimizationBargainTeamTask = new SpuOptimizationBargainTeamTask()
{
Id = idGenerator.NewLong(),
BelongTeamId = department.Id,
BelongTeamName = department.DepartmentName,
CompletionTime = null,
IsOptimizationCompleted = false,
SpuOptimizationTaskId = spuOptimizationTask.Id
};
insertSpuOptimizationBargainTeamTaskList.Add(spuOptimizationBargainTeamTask);
#region 创建采购方案竞标任务
var waitJoinSchemeList = waitToCompetitiveTenderSchemeList.Where(ps => ps.BelongBargainTeamId == department.Id &&
qtskus.Contains(ps.SkuId))
.ToList();
//var waitJoinSchemeIdList = waitJoinSchemeList.Select(ps => ps.Id).ToList();
//var waitJonPurchaserList = waitToCompetitiveTenderSchemePurchaserList.Where(x => waitJoinSchemeIdList.Contains(x.SkuPurchaseSchemeId));
if (waitJoinSchemeList.Count() > 0)
{
insertSpuOptimizationCompetitiveTenderTaskList.AddRange(waitJoinSchemeList.Select(ps => new SpuOptimizationCompetitiveTenderTask()
{
Id = idGenerator.NewLong(),
BargainTeamId = ps.BelongBargainTeamId,
CreateTime = DateTime.Now,
IsUpdateQuotedPrice = false,
SchemeGroupId = ps.SchemeGroupId,
SchemeId = ps.Id,
SkuId = ps.SkuId,
SpuOptimizationBargainTeamTaskId = spuOptimizationBargainTeamTask.Id,
SpuOptimizationTaskId = spuOptimizationTask.Id,
UpdateTime = DateTime.Now
}));
//insertSpuOptimizationPurchaserCompetitiveTenderTaskList.AddRange(waitJonPurchaserList.Select(x =>
//{
// var ps = waitJoinSchemeList.FirstOrDefault(ps => ps.Id == x.SkuPurchaseSchemeId);
// return new SpuOptimizationPurchaserCompetitiveTenderTask()
// {
// Id = idGenerator.NewLong(),
// BargainTeamId = ps.BelongBargainTeamId,
// CreateTime = DateTime.Now,
// UpdateTime = DateTime.Now,
// IsUpdateQuotedPrice = false,
// PurchaserId = x.PurchaserId,
// SchemeGroupId = ps.SchemeGroupId,
// SchemeId = ps.Id,
// SkuId = ps.SkuId,
// SpuOptimizationTaskId = spuOptimizationTask.Id
// };
//}));
}
#endregion
}
#endregion
#region 创建优化限时任务
{
//判断sku是否首次采购
//var isFirst = !dbSpuTotalInfoList.Any(s => s.ProductId == productId);
insertTimeLimitTaskList.Add(new TimeLimitTask()
{
Id = idGenerator.NewLong(),
CreateTme = DateTime.Now,
//ExpirationTime = DateTime.Now.AddDays(isFirst ? 2 : 1),
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now),
//OrderId = o.OrderId,
//OrderSn = o.OrderSn,
ShopId = shopId,
//SkuId = waitCheckOrderSku.SkuId,
TaskType = Enums.TimeLimitTaskType.,
TaskId = spuOptimizationTask.Id,
Remark = "首次采购限时任务"
});
}
#endregion
}
fsql.Transaction(() =>
{
if (insertSpuOptimizationTaskList.Count() > 0)
fsql.Insert(insertSpuOptimizationTaskList).ExecuteAffrows();
if (insertSkuOptimizationTaskList.Count() > 0)
fsql.Insert(insertSkuOptimizationTaskList).ExecuteAffrows();
if (insertSpuOptimizationBargainTeamTaskList.Count() > 0)
fsql.Insert(insertSpuOptimizationBargainTeamTaskList).ExecuteAffrows();
if (insertSpuOptimizationCompetitiveTenderTaskList.Count() > 0)
fsql.Insert(insertSpuOptimizationCompetitiveTenderTaskList).ExecuteAffrows();
//if (insertSpuOptimizationPurchaserCompetitiveTenderTaskList.Count() > 0)
// fsql.Insert(insertSpuOptimizationPurchaserCompetitiveTenderTaskList).ExecuteAffrows();
if (insertTimeLimitTaskList.Count() > 0)
fsql.Insert(insertTimeLimitTaskList).ExecuteAffrows();
});
}
/// <summary>
/// 更新报价
/// </summary>
/// <param name="request"></param>
/// <param name="userId"></param>
public void BatchUpdateCompetitiveTenderQuotation(BatchUpdateCompetitiveTenderQuotationRequest request, string userId)
{
#region 获取用户和部门信息
var uInfo = userBusiness.GetisBargainTeamByUserId(userId, true);
#endregion
#region 业务验证
var spuOptimizationTask = fsql.Select<SpuOptimizationTask>(request.SpuOptimizationTaskId).ToOne();
if (spuOptimizationTask == null)
throw new BusinessException($"待优化任务{request.SpuOptimizationTaskId}不存在");
var spuOptimizationBargainTeamTask = fsql.Select<SpuOptimizationBargainTeamTask>().Where(sbt => sbt.SpuOptimizationTaskId == request.SpuOptimizationTaskId && sbt.BelongTeamId == uInfo.bargainTeam.Id).ToOne();
if (spuOptimizationBargainTeamTask == null)
throw new BusinessException($"待优化任务{request.SpuOptimizationTaskId}中不存在议价组{uInfo.bargainTeam.Id}/{uInfo.bargainTeam.DepartmentName}的子任务");
var skuIdList = fsql.Select<SkuOptimizationTask>().Where(s => s.SpuOptimizationTaskId == request.SpuOptimizationTaskId).ToList(s => s.SkuId);
#endregion
#region DBOperation
List<SpuOptimizationCompetitiveTenderTask> insertSpuOptimizationCompetitiveTenderTaskList = new List<SpuOptimizationCompetitiveTenderTask>();
List<long> updateCompetitiveTenderTaskIdList = new List<long>();
List<SpuOptimizationProductSkuUpdateQuotedPriceRecord> insertUpdatePriceList = new List<SpuOptimizationProductSkuUpdateQuotedPriceRecord>();
#endregion
//var skuList = request.ItemList.Select(x => x.SkuId).Distinct().ToList();
var purchaseSkuIdList = request.ItemList.Select(x => x.PurchaseSkuId).Distinct().ToList();
//查询竞标任务
var competitiveTenderTaskList = fsql.Select<SpuOptimizationCompetitiveTenderTask>()
.Where(ct => ct.BargainTeamId == uInfo.bargainTeam.Id &&
ct.SpuOptimizationTaskId == request.SpuOptimizationTaskId &&
ct.SchemeGroupId == request.SchemeGroupId)
.ToList();
//查询配件关联的采购方案
var relationPurchaseSchemeIdList = fsql.Select<PurchaseScheme>()
.Where(ps => ps.SchemeGroupId == request.SchemeGroupId &&
ps.BelongBargainTeamId == uInfo.bargainTeam.Id &&
fsql.Select<PurchaseSchemeProductSku>()
.Where(pss => skuIdList.Contains(pss.SkuId) &&
purchaseSkuIdList.Contains(pss.PurchaseSkuId) &&
pss.SkuPurchaseSchemeId == ps.Id).Any())
.ToList(ps => ps.Id);
var relationPurchaseSchemeList = purchaseSchemeBusiness.GetPurchaseSchemeList(new QuerySchemeRequest()
{
SchemeIdList = relationPurchaseSchemeIdList,
IncludePurchaseSkuBasicInfo = 0
});
//查询配件级报价任务
var updatePriceRecordList = fsql.Select<SpuOptimizationProductSkuUpdateQuotedPriceRecord>()
.Where(x => x.SpuOptimizationTaskId == request.SpuOptimizationTaskId &&
x.BargainTeamId == uInfo.bargainTeam.Id)
.ToList();
//筛选出不在竞标任务中的采购方案
var noJoinCompetitiveTenderPurchaseSchemeList = relationPurchaseSchemeList.Where(ps => !competitiveTenderTaskList.Any(ct => ct.SchemeId == ps.Id)).ToList();
{
var batchEditPurchaseSkuActualPriceRequest = request.Map<BatchEditPurchaseSkuActualPriceRequest>();
batchEditPurchaseSkuActualPriceRequest.ProductId = spuOptimizationTask.ProductId;
purchaseSchemeBusiness.BatchEditPurchaseSkuActualPrice(batchEditPurchaseSkuActualPriceRequest, uInfo);
}
insertUpdatePriceList.AddRange(request.ItemList.Where(x => !updatePriceRecordList.Any(r => r.PurchaseSkuId == x.PurchaseSkuId)).Select(x => new SpuOptimizationProductSkuUpdateQuotedPriceRecord()
{
Id = idGenerator.NewLong(),
BargainTeamId = uInfo.bargainTeam.Id,
CreateTime = DateTime.Now,
PurchaseSkuId = x.PurchaseSkuId,
SpuOptimizationTaskId = request.SpuOptimizationTaskId,
UserId = uInfo.user.Id
}));
if (noJoinCompetitiveTenderPurchaseSchemeList.Count() > 0)
{
insertSpuOptimizationCompetitiveTenderTaskList.AddRange(noJoinCompetitiveTenderPurchaseSchemeList.Select(ps => new SpuOptimizationCompetitiveTenderTask()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
BargainTeamId = uInfo.bargainTeam.Id,
IsUpdateQuotedPrice = true,
SchemeGroupId = ps.SchemeGroupId,
SchemeId = ps.Id,
SkuId = ps.SkuId,
SpuOptimizationBargainTeamTaskId = spuOptimizationBargainTeamTask.Id,
SpuOptimizationTaskId = request.SpuOptimizationTaskId,
UpdateTime = DateTime.Now
}));
}
if (competitiveTenderTaskList.Count() > 0)
{
//updateCompetitiveTenderTaskIdList.AddRange(competitiveTenderTaskList.Select(ct => ct.Id).ToList());
foreach (var ctTask in competitiveTenderTaskList)
{
if (ctTask.IsUpdateQuotedPrice == true)
continue;
var scheme = relationPurchaseSchemeList.FirstOrDefault(ps => ps.Id == ctTask.SchemeId);
if (scheme == null)
continue;
var pssList = scheme.PurchaseSchemeProductList.SelectMany(psp => psp.PurchaseSchemeProductSkuList);
if (pssList.Any(pss => request.ItemList.Any(item => item.PurchaseSkuId == pss.PurchaseSkuId)))
{
//ctTask.IsUpdateQuotedPrice = true;
updateCompetitiveTenderTaskIdList.Add(ctTask.Id);
}
}
}
fsql.Transaction(() =>
{
if (insertSpuOptimizationCompetitiveTenderTaskList.Count() > 0)
fsql.Insert(insertSpuOptimizationCompetitiveTenderTaskList).ExecuteAffrows();
if (updateCompetitiveTenderTaskIdList.Count() > 0)
fsql.Update<SpuOptimizationCompetitiveTenderTask>(updateCompetitiveTenderTaskIdList)
.Set(ct => ct.IsUpdateQuotedPrice, true)
.Set(ct => ct.UpdateTime, DateTime.Now)
.ExecuteAffrows();
if (insertUpdatePriceList.Count() > 0)
fsql.Insert(insertUpdatePriceList).ExecuteAffrows();
});
}
/// <summary>
/// 完成优化
/// </summary>
/// <param name="taskId"></param>
/// <param name="userId"></param>
/// <exception cref="BusinessException"></exception>
public void CompleteOptimization(long taskId, string userId)
{
#region 获取用户和部门信息
var uInfo = userBusiness.GetisBargainTeamByUserId(userId, true);
#endregion
#region 业务验证
var spuOptimizationTask = fsql.Select<SpuOptimizationTask>(taskId).ToOne();
if (spuOptimizationTask == null)
throw new BusinessException($"待优化任务{taskId}不存在");
if (spuOptimizationTask.IsOptimizationCompleted == true)
throw new BusinessException("待优化任务已完成");
var spuOptimizationBargainTeamTaskList = fsql.Select<SpuOptimizationBargainTeamTask>()
.Where(sbt => sbt.SpuOptimizationTaskId == taskId)
.ToList();
var currentspuOptimizationBargainTeamTask = spuOptimizationBargainTeamTaskList.FirstOrDefault(sc => sc.BelongTeamId == uInfo.bargainTeam.Id);
if (currentspuOptimizationBargainTeamTask == null)
throw new BusinessException($"未找到议价组{uInfo.bargainTeam.DepartmentName}的议价子任务");
if (currentspuOptimizationBargainTeamTask.IsOptimizationCompleted == true)
throw new BusinessException($"{uInfo.bargainTeam.DepartmentName}的议价子任务已完成");
var skuIdList = fsql.Select<SkuOptimizationTask>()
.Where(s => s.SpuOptimizationTaskId == taskId)
.ToList(s => s.SkuId);
//查询全部竞标任务
var allBargainTeamCompetitiveTenderTaskList = fsql.Select<SpuOptimizationCompetitiveTenderTask>()
.Where(ct => ct.SpuOptimizationTaskId == taskId)
.ToList();
//查询当前议价组的竞标任务
var currentBargainTeamCompetitiveTenderTaskList = allBargainTeamCompetitiveTenderTaskList.Where(ct => ct.BargainTeamId == uInfo.bargainTeam.Id).ToList();
if (currentBargainTeamCompetitiveTenderTaskList.Count() == 0)
throw new BusinessException($"议价组{uInfo.bargainTeam.DepartmentName}没有参与竞标的采购方案,不能完成优化任务");
var currentBargainTeamCompetitiveTenderSchemeIdList = currentBargainTeamCompetitiveTenderTaskList.Select(ct => ct.SchemeId).ToList();
#region 验证该议价组的符合sku条件的采购方案是否都参与投标
var waitCheckPurchaseSchemeIdList = fsql.Select<PurchaseScheme>()
.Where(ps => ps.BelongBargainTeamId == uInfo.bargainTeam.Id &&
skuIdList.Contains(ps.SkuId))
.ToList(ps => ps.Id);
if (waitCheckPurchaseSchemeIdList.Count() == 0)
throw new BusinessException($"议价组{uInfo.bargainTeam.DepartmentName}没有参与竞标的采购方案,不能完成优化任务");
var noJoinCompetitiveTenderSchemeIdList = waitCheckPurchaseSchemeIdList.Except(currentBargainTeamCompetitiveTenderSchemeIdList);
if (noJoinCompetitiveTenderSchemeIdList.Count() > 0)
throw new BusinessException($"议价组{uInfo.bargainTeam.DepartmentName}存在{noJoinCompetitiveTenderSchemeIdList.Count()}个符合条件但未参与竞标的采购方案");
#endregion
#region 验证该议价组参与投标的采购方案是否都完成报价
if (currentBargainTeamCompetitiveTenderTaskList.Any(ct => ct.IsUpdateQuotedPrice == false))
throw new BusinessException($"议价组{uInfo.bargainTeam.DepartmentName}存在未更新报价的投标");
#endregion
currentspuOptimizationBargainTeamTask.IsOptimizationCompleted = true;
#endregion
IUpdate<SpuOptimizationBargainTeamTask> updateBargainTask = null;
IUpdate<SpuOptimizationTask> updateSpuTask = null;
IUpdate<SpuTotalSaleInfo> updateSpuSaleInfo = null;
IUpdate<TimeLimitTask> updateTimeLimitTask = null;
IUpdate<SpuOptimizationCompetitiveTenderTask> updateCompetitiveTenderTask = null;
if (!spuOptimizationBargainTeamTaskList.Any(sc => sc.IsOptimizationCompleted == false))
{
//全部完成
#region 更新spu销量表
var spuSaleInfo = fsql.Select<SpuTotalSaleInfo>(spuOptimizationTask.ProductId).ToOne();
if (spuSaleInfo == null)
throw new BusinessException($"未找到spu{spuOptimizationTask.ProductId}销量");
updateSpuSaleInfo = fsql.Update<SpuTotalSaleInfo>(spuOptimizationTask.ProductId)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.IsFirstPurchaseCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.FirstPurchaseCompletedItemCount == s.ItemCount)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.IsFirstOptimizationCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.FirstOptimizationCompletedItemCount == s.ItemCount)
.Set(s => s.LastOptimizationItemCount == s.ItemCount)
.Set(s => s.LastOptimizationTime, DateTime.Now)
.Set(s => s.UpdateTime, DateTime.Now);
#endregion
#region 更新待优化任务
updateSpuTask = fsql.Update<SpuOptimizationTask>(spuOptimizationTask.Id)
.Set(t => t.IsOptimizationCompleted, true)
.Set(t => t.CompletionTime, DateTime.Now);
#endregion
#region 更新待优化限时任务
updateTimeLimitTask = fsql.Update<TimeLimitTask>().Set(t => t.CompletionTime, DateTime.Now)
.Set(t => t.IsTimely == (DateTime.Now < t.ExpirationTime ? true : false))
.Where(t => t.TaskId == spuOptimizationTask.Id &&
t.CompletionTime == null &&
t.TaskType == Enums.TimeLimitTaskType.);
#endregion
#region 评选中标结果
var allBargainTeamCompetitiveTenderSchemeIdList = allBargainTeamCompetitiveTenderTaskList.Select(ct => ct.SchemeId).ToList();
var allBargainTeamPurchaseSchemeList = purchaseSchemeBusiness.GetPurchaseSchemeList(new QuerySchemeRequest()
{
SchemeIdList = allBargainTeamCompetitiveTenderSchemeIdList,
IncludePurchaseSkuBasicInfo = 0
});
var victoryCompetitiveTenderTaskList = VictoryPlanSelection(allBargainTeamCompetitiveTenderTaskList, allBargainTeamPurchaseSchemeList);
var victoryCompetitiveTenderTaskIdList = victoryCompetitiveTenderTaskList.Select(ct => ct.Id).ToList();
updateCompetitiveTenderTask = fsql.Update<SpuOptimizationCompetitiveTenderTask>(victoryCompetitiveTenderTaskIdList)
.Set(ct => ct.IsWin, true);
#endregion
}
#region 更新待优化议价组任务
updateBargainTask = fsql.Update<SpuOptimizationBargainTeamTask>(currentspuOptimizationBargainTeamTask.Id)
.Set(sc => sc.IsOptimizationCompleted, true)
.Set(sc => sc.CompletionTime, DateTime.Now);
#endregion
fsql.Transaction(() =>
{
updateSpuTask?.ExecuteAffrows();
updateBargainTask?.ExecuteAffrows();
updateSpuSaleInfo?.ExecuteAffrows();
updateTimeLimitTask?.ExecuteAffrows();
updateCompetitiveTenderTask?.ExecuteAffrows();
});
}
/// <summary>
/// 查询待优化任务
/// </summary>
/// <param name="request"></param>
/// <param name="userId"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
public ListResponse<SpuOptimizationTaskResponse> GetNoCompletionSkuOptimizationTask(QueryNoCompletionOptimizationTaskRequest request, string userId)
{
request.EndTime = request.EndTime.Date.AddDays(1).AddSeconds(-1);
var uInfo = userBusiness.GetisBargainTeamByUserId(userId);
ISelect<SpuOptimizationTask> select = null;
if (request.SpuOptimizationTaskId != null && request.SpuOptimizationTaskId != 0)
{
select = fsql.Select<SpuOptimizationTask>(request.SpuOptimizationTaskId);
}
else
{
string spuKeyWords = string.Empty, skuKeyWords = string.Empty;
if (!string.IsNullOrEmpty(request.SpuOrSku))
{
if (Regex.IsMatch(request.SpuOrSku, @"^\d{2,10}$"))
spuKeyWords = request.SpuOrSku;
else if (Regex.IsMatch(request.SpuOrSku, @"^\w{2,20}$"))
skuKeyWords = request.SpuOrSku;
}
select = fsql.Select<SpuOptimizationTask>()
.Where(t => t.IsOptimizationCompleted == false &&
t.CreateTime >= request.StartTime &&
t.CreateTime <= request.EndTime)
.WhereIf(request.BelongShopId != null && request.BelongShopId != 0, t => t.BelongShopId == request.BelongShopId)
.WhereIf(!string.IsNullOrEmpty(request.JDSku) ||
!string.IsNullOrEmpty(skuKeyWords), t => fsql.Select<SkuOptimizationTask>()
.Where(st => st.SpuOptimizationTaskId == t.Id)
.WhereIf(!string.IsNullOrEmpty(request.JDSku), st => st.JDSkuId == request.JDSku)
.WhereIf(!string.IsNullOrEmpty(skuKeyWords), st => st.SkuId == skuKeyWords)
.Any())
.WhereIf(!string.IsNullOrEmpty(request.TitleKeywords), t => t.ProductTitle.Contains(request.TitleKeywords))
.WhereIf(!string.IsNullOrEmpty(spuKeyWords), t => t.ProductId == spuKeyWords);
}
var taskList = select.OrderByDescending(t => t.CreateTime)
.Count(out var total)
.Page(request.PageIndex, request.PageSize)
.ToList<SpuOptimizationTaskResponse>();
if (taskList.Count() == 0)
return new ListResponse<SpuOptimizationTaskResponse>() { TotalCount = 0, Items = null };
var spuTaskIdList = taskList.Select(t => t.Id).ToList();
#region 获取议价组任务
var bargainTeamTaskList = fsql.Select<SpuOptimizationBargainTeamTask>()
.Where(sbt => spuTaskIdList.Contains(sbt.SpuOptimizationTaskId))
.ToList<SpuOptimizationBargainTeamTaskResponse>();
var bargainTeamIdList = bargainTeamTaskList.Select(x => x.BelongTeamId).Distinct().ToList();
#endregion
#region 获取SKU优化任务
var skuTaskList = fsql.Select<SkuOptimizationTask, Model.Db.ProductSku>()
.LeftJoin((st, ps) => st.SkuId == ps.Id)
.Where((st, ps) => spuTaskIdList.Contains(st.SpuOptimizationTaskId))
.ToList((st, ps) => new SkuOptimizationTaskResponse
{
CreateTime = st.CreateTime,
Id = st.Id,
JDSkuId = st.JDSkuId,
Logo = ps.Logo,
PreItemCount = st.PreItemCount,
PrePurchaseAmount = st.PrePurchaseAmount,
SkuId = st.SkuId,
SpuOptimizationTaskId = st.SpuOptimizationTaskId,
SkuName = ps.SkuName,
Price = ps.Price
});
var skuIdList = skuTaskList.Select(st => st.SkuId).ToList();
#endregion
#region 限时任务
var timelimitTaskList = fsql.Select<TimeLimitTask>()
.Where(t => t.TaskType == Enums.TimeLimitTaskType. && spuTaskIdList.Contains(t.TaskId))
.ToList<TimeLimitTaskResponse>();
#endregion
#region 获取采购方案
if (skuIdList.Count() == 0 && bargainTeamIdList.Count() == 0)
return new ListResponse<SpuOptimizationTaskResponse>()
{
Items = null,
TotalCount = 0
};
var purchaseSchemeList = purchaseSchemeBusiness.GetPurchaseSchemeList(new QuerySchemeRequest()
{
SkuIdList = skuIdList,
BargainTeamIdList = bargainTeamIdList,
IncludePurchaseSkuBasicInfo = 1,
IncludePurchaseSkuStatisticsInfo = 1
});
#endregion
#region 获取采购方案分组
var purchaseSchemeGroupIdList = purchaseSchemeList.Select(ps => ps.SchemeGroupId).Distinct().ToList();
var purchaseSchemeGroupList = fsql.Select<PurchaseSchemeGroup>(purchaseSchemeGroupIdList).ToList<PurchaseSchemeGroupResponse>();
#endregion
foreach (var task in taskList)
{
task.BargainTeamTaskList = bargainTeamTaskList.Where(sbt => sbt.SpuOptimizationTaskId == task.Id).ToList();
task.TimeLimitTask = timelimitTaskList.FirstOrDefault(t => t.TaskId == task.Id);
if (task.TimeLimitTask != null)
task.TimeLimitTask.RemainingTime = timeLimitRules.CalculateLessTimeForWorkHour(task.TimeLimitTask.ExpirationTime.Value);
task.IsCompletedByCurrentTeam = task.BargainTeamTaskList.FirstOrDefault(sbt => sbt.BelongTeamId == uInfo.bargainTeam?.Id)?.IsOptimizationCompleted == true;
task.SkuOptimizationTaskList = skuTaskList.Where(st => st.SpuOptimizationTaskId == task.Id).ToList();
#region 组装sku优化任务的采购方案信息
foreach (var skuTask in task.SkuOptimizationTaskList)
{
skuTask.RelationSchemeList = purchaseSchemeList.Where(ps => ps.SkuId == skuTask.SkuId)
.Select(ps => new SkuOptimizationTaskPurchaseSchemeResponse()
{
SchemeId = ps.Id,
SchemeGroupId = ps.SchemeGroupId,
IsFreeFreight = ps.IsFreeFreight,
LastPurchasePriceCost = ps.LastPurchasePriceCost,
PurchaseSchemeCost = ps.BargainingCost ?? ps.DefaultCost
}).ToList();
}
#endregion
#region 合并分组/采购商/配件
var currentTaskSkuIdList = task.SkuOptimizationTaskList.Select(st => st.SkuId).ToList();
var currentPurchaseSchemeGroups = purchaseSchemeList.Where(p => currentTaskSkuIdList.Contains(p.SkuId) &&
p.BelongBargainTeamId == uInfo.bargainTeam?.Id)
.GroupBy(p => p.SchemeGroupId)
.ToList();
task.MergePurchaseScemeGroupList = new List<MergePurchaseSchemeGroupResponse>();
foreach (var schemeGroup in currentPurchaseSchemeGroups)
{
var mergeSchemeGroup = new MergePurchaseSchemeGroupResponse()
{
Id = schemeGroup.Key,
GroupName = purchaseSchemeGroupList.FirstOrDefault(g => g.Id == schemeGroup.Key)?.GroupName
};
task.MergePurchaseScemeGroupList.Add(mergeSchemeGroup);
var schemeList = schemeGroup.ToList();
foreach (var scheme in schemeList)
{
foreach (var psp in scheme.PurchaseSchemeProductList)
{
var mergePurchaser = mergeSchemeGroup.PurchaserList.FirstOrDefault(p => p.Id == psp.PurchaserId);
if (mergePurchaser == null)
{
mergePurchaser = scheme.PurchaserList.FirstOrDefault(p => p.Id == psp.PurchaserId)?.Map<MergePurchaserResponse>();
if (mergePurchaser == null)
throw new BusinessException($"匹配采购商异常 schemeId {scheme.Id} pspProductId {psp.ProductId}");
mergeSchemeGroup.PurchaserList.Add(mergePurchaser);
}
foreach (var pss in psp.PurchaseSchemeProductSkuList)
{
var mergePss = mergePurchaser.MergePurchaseSchemeProductSkuList.FirstOrDefault(mpss => mpss.PurchaseSkuId == pss.PurchaseSkuId);
if (mergePss == null)
{
mergePss = pss.Map<MergePurchaseSchemeProductSkuResponse>();
mergePss.PurchaserId = mergePurchaser.Id;
mergePss.BelongSkuIdList.Add(pss.SkuId);
mergePss.PurchaseUrl = psp.PurchaseUrl;
mergePurchaser.MergePurchaseSchemeProductSkuList.Add(mergePss);
}
else if (!mergePss.BelongSkuIdList.Contains(pss.SkuId))
mergePss.BelongSkuIdList.Add(pss.SkuId);
}
}
}
}
#endregion
}
return new ListResponse<SpuOptimizationTaskResponse>()
{
Items = taskList,
TotalCount = total
};
}
/// <summary>
/// 评选结果
/// </summary>
/// <param name="competitiveTenderTaskList"></param>
/// <param name="purchaseSchemeList"></param>
/// <returns></returns>
private IList<SpuOptimizationCompetitiveTenderTask> VictoryPlanSelection(IList<SpuOptimizationCompetitiveTenderTask> competitiveTenderTaskList,
IList<PurchaseSchemeResponse> purchaseSchemeList)
{
var victoryList = new List<SpuOptimizationCompetitiveTenderTask>();
var psGroups = purchaseSchemeList.GroupBy(ps => ps.SchemeGroupId);
var winGroupKey = psGroups.Select(g => new { SchemeGroupId = g.Key, Cost = g.Sum(ps => ps.BargainingCost ?? ps.DefaultCost) })
.OrderByDescending(x => x.Cost)
.FirstOrDefault();
victoryList.AddRange(competitiveTenderTaskList.Where(ct => ct.SchemeGroupId == winGroupKey.SchemeGroupId));
//foreach (var psGroup in psGroups)
//{
// var psListOrderByCostDescList = psGroup.OrderByDescending(ps => ps.BargainingCost ?? ps.DefaultCost).ToList();
// var minCostScheme = psListOrderByCostDescList.FirstOrDefault();
// var competitiveTenderTask = competitiveTenderTaskList.FirstOrDefault(ct => ct.SchemeId == minCostScheme.Id);
// victoryList.Add(competitiveTenderTask);
//}
return victoryList;
}
/// <summary>
/// 限时任务超时回调
/// </summary>
/// <param name="taskId"></param>
public void TimeLimitTaskTimeOutCallBack(long taskId)
{
try
{
var spuOptimizationTask = fsql.Select<SpuOptimizationTask>(taskId).ToOne();
if (spuOptimizationTask == null)
throw new BusinessException($"待优化任务{taskId}不存在");
if (spuOptimizationTask.IsOptimizationCompleted == true)
throw new BusinessException("待优化任务已完成");
IUpdate<SpuOptimizationTask> updateSpuTask = null;
IUpdate<SpuTotalSaleInfo> updateSpuSaleInfo = null;
IUpdate<SpuOptimizationCompetitiveTenderTask> updateCompetitiveTenderTask = null;
var spuOptimizationBargainTeamTaskList = fsql.Select<SpuOptimizationBargainTeamTask>()
.Where(sbt => sbt.SpuOptimizationTaskId == taskId)
.ToList();
if (spuOptimizationBargainTeamTaskList.Any(sc => sc.IsOptimizationCompleted == true))
{
//任意一个议价组完成任务,该优化任务视为完成
var compleptionBargainTeamIdList = spuOptimizationBargainTeamTaskList.Where(sbt => sbt.IsOptimizationCompleted == true)
.Select(sbt => sbt.BelongTeamId)
.Distinct()
.ToList();
//已完成议价任务的竞标任务
var compleptionBargainTeamCompetitiveTenderTaskList = fsql.Select<SpuOptimizationCompetitiveTenderTask>()
.Where(ct => ct.SpuOptimizationTaskId == taskId &&
compleptionBargainTeamIdList.Contains(ct.BargainTeamId))
.ToList();
#region 更新spu销量表
var spuSaleInfo = fsql.Select<SpuTotalSaleInfo>(spuOptimizationTask.ProductId).ToOne();
if (spuSaleInfo == null)
throw new BusinessException($"未找到spu{spuOptimizationTask.ProductId}销量");
updateSpuSaleInfo = fsql.Update<SpuTotalSaleInfo>(spuOptimizationTask.ProductId)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.IsFirstPurchaseCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == false, s => s.FirstPurchaseCompletedItemCount == s.ItemCount)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.IsFirstOptimizationCompleted, true)
.SetIf(spuSaleInfo.IsFirstPurchaseCompleted == true &&
spuSaleInfo.IsFirstOptimizationCompleted == false, s => s.FirstOptimizationCompletedItemCount == s.ItemCount)
.Set(s => s.LastOptimizationItemCount == s.ItemCount)
.Set(s => s.LastOptimizationTime, DateTime.Now)
.Set(s => s.UpdateTime, DateTime.Now);
#endregion
#region 更新待优化任务
updateSpuTask = fsql.Update<SpuOptimizationTask>(spuOptimizationTask.Id)
.Set(t => t.IsOptimizationCompleted, true)
.Set(t => t.CompletionTime, DateTime.Now);
#endregion
#region 评选竞标结果
var compleptionBargainTeamPurchaseSchemeIdList = compleptionBargainTeamCompetitiveTenderTaskList.Select(ct => ct.SchemeId).ToList();
var compleptionBargainTeamPurchaseSchemeList = purchaseSchemeBusiness.GetPurchaseSchemeList(new QuerySchemeRequest()
{
SchemeIdList = compleptionBargainTeamPurchaseSchemeIdList,
IncludePurchaseSkuBasicInfo = 0
});
var victoryCompetitiveTenderTaskList = VictoryPlanSelection(compleptionBargainTeamCompetitiveTenderTaskList, compleptionBargainTeamPurchaseSchemeList);
var victoryCompetitiveTenderTaskIdList = victoryCompetitiveTenderTaskList.Select(ct => ct.Id).ToList();
updateCompetitiveTenderTask = fsql.Update<SpuOptimizationCompetitiveTenderTask>(victoryCompetitiveTenderTaskIdList)
.Set(ct => ct.IsWin, true);
#endregion
}
fsql.Transaction(() =>
{
updateSpuTask?.ExecuteAffrows();
updateSpuSaleInfo?.ExecuteAffrows();
updateCompetitiveTenderTask?.ExecuteAffrows();
});
}
catch (Exception ex)
{
nLogManager.Default().Error(ex, "限时任务超时回调失败");
}
}
/// <summary>
/// 从优化任务模块删除采购方案分组(级联删除采购分组下的其他)
/// </summary>
/// <param name="request"></param>
public void DeleteSchemeGroup(DeleteSchemeGroupFromSpuOptimizationTaskRequest request, string userId)
{
_ = userBusiness.GetisBargainTeamByUserId(userId, true);
var schemeIdList = fsql.Select<PurchaseScheme>().Where(ps => ps.SchemeGroupId == request.SchemeGroupId).ToList(ps => ps.Id);
fsql.Transaction(() =>
{
fsql.Delete<PurchaseSchemeGroup>(request.SchemeGroupId).ExecuteAffrows();
if (schemeIdList.Count() > 0)
{
fsql.Delete<PurchaseScheme>(schemeIdList).ExecuteAffrows();
fsql.Delete<PurchaseSchemeProduct>().Where(psp => schemeIdList.Contains(psp.SkuPurchaseSchemeId)).ExecuteAffrows();
fsql.Delete<PurchaseSchemeProductSku>().Where(pss => schemeIdList.Contains(pss.SkuPurchaseSchemeId)).ExecuteAffrows();
}
fsql.Delete<SpuOptimizationCompetitiveTenderTask>()
.Where(ct => ct.SchemeGroupId == request.SchemeGroupId &&
ct.SpuOptimizationTaskId == request.SpuOptimizationId)
.ExecuteAffrows();
});
//var competitiveTenderTaskList = fsql.Select<SpuOptimizationCompetitiveTenderTask>()
// .Where(ct => ct.SpuOptimizationTaskId == request.SpuOptimizationId &&
// ct.SchemeGroupId == request.SchemeGroupId)
// .ToList();
//var schemeIdList = competitiveTenderTaskList.Select(ct => ct.SchemeId).ToList();
//purchaseSchemeBusiness.DeletePurchaseScheme(schemeIdList);
//var ctTaskIdList = competitiveTenderTaskList.Select(ct => ct.Id);
//fsql.Delete<SpuOptimizationCompetitiveTenderTask>(ctTaskIdList).ExecuteAffrows();
}
public long GetNoCompletedSpuOptimizationTaskCount()
{
return fsql.Select<SpuOptimizationTask>().Where(t => t.IsOptimizationCompleted == false).Count();
}
}
}

478
BBWYB.Server.Business/Sync/OrderSyncBusiness.cs

@ -2,6 +2,8 @@
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Db.BBWY;
using BBWYB.Server.Model.Db.SpuOptimization;
using BBWYB.Server.Model.Dto;
using FreeSql;
using Newtonsoft.Json.Linq;
@ -17,12 +19,29 @@ namespace BBWYB.Server.Business.Sync
private OP_PlatformClientFactory opPlatformClientFactory;
private VenderBusiness venderBusiness;
private TaskSchedulerManager taskSchedulerManager;
public OrderSyncBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, OP_PlatformClientFactory opPlatformClientFactory, VenderBusiness venderBusiness, TaskSchedulerManager taskSchedulerManager) : base(fsql, nLogManager, idGenerator)
private List<Enums.TimeLimitTaskType> timeLimitTaskTypes;
private TimeLimitRules timeLimitRules;
private FreeSqlMultiDBManager fsqlManager;
public OrderSyncBusiness(IFreeSql fsql,
NLogManager nLogManager,
IIdGenerator idGenerator,
OP_PlatformClientFactory opPlatformClientFactory,
VenderBusiness venderBusiness,
TaskSchedulerManager taskSchedulerManager,
TimeLimitRules timeLimitRules,
FreeSqlMultiDBManager fsqlManager) : base(fsql, nLogManager, idGenerator)
{
this.opPlatformClientFactory = opPlatformClientFactory;
this.venderBusiness = venderBusiness;
this.taskSchedulerManager = taskSchedulerManager;
timeLimitTaskTypes = new List<Enums.TimeLimitTaskType>()
{
Enums.TimeLimitTaskType.,
Enums.TimeLimitTaskType.
};
this.timeLimitRules = timeLimitRules;
this.fsqlManager = fsqlManager;
}
public void AutoOrderSync()
@ -90,21 +109,59 @@ namespace BBWYB.Server.Business.Sync
var qtOrderIdList = qtOrderList.Items.Select(qto => qto.OrderId).ToList();
var dbOrderList = fsql.Select<Model.Db.Order>(qtOrderIdList).ToList();
//采购限时任务列表
var payedQTOrderIdList = qtOrderList.Items.Where(qto => qto.IsPay).Select(qto => qto.OrderId).ToList();
var dbPurchaseTimeLimitTaskList = fsql.Select<TimeLimitTask>().Where(t => t.TaskType == Enums.TimeLimitTaskType. &&
payedQTOrderIdList.Contains(t.OrderId)).ToList();
var payedQTSpuIdList = qtOrderList.Items.Where(qto => qto.IsPay).SelectMany(qto => qto.OrderSkuList).Select(qtos => qtos.ProductId).Distinct().ToList();
var payedQTSkuIdList = qtOrderList.Items.Where(qto => qto.IsPay).SelectMany(qto => qto.OrderSkuList).Select(qtos => qtos.SkuId).Distinct().ToList();
//限时任务列表
var dbTimeLimitTaskList = fsql.Select<TimeLimitTask>().Where(t => timeLimitTaskTypes.Contains(t.TaskType.Value) &&
payedQTOrderIdList.Contains(t.OrderId)).ToList();
//限时采购任务列表
var dbPurchaseTimeLimitTaskList = dbTimeLimitTaskList.Where(t => t.TaskType == Enums.TimeLimitTaskType.).ToList();
//限时议价任务列表
var dbOptimizationLimitTaskList = dbTimeLimitTaskList.Where(t => t.TaskType == Enums.TimeLimitTaskType.).ToList();
//现有sku销量
var dbSkuTotalSaleInfoList = fsql.Select<SkuTotalSaleInfo>().Where(s => s.ShopId == shopId && s.IsEnabled == true && payedQTSkuIdList.Contains(s.SkuId))
.ToList();
//现有spu销量
var dbSpuTotalSaleInfoList = fsql.Select<SpuTotalSaleInfo>().Where(s => s.ShopId == shopId && s.IsEnabled == true && payedQTSpuIdList.Contains(s.ProductId))
.ToList();
#region DB Operation
List<Model.Db.Order> insertOrderList = new List<Model.Db.Order>();
List<OrderSku> insertOrderSkuList = new List<OrderSku>();
//List<long> updateOrderSkuIdList_OptimizationFlag = new List<long>();
Dictionary<Enums.TriggerOptimizationReason, List<long>> updateOSkuOptimizationFlagByReasonGroups = new Dictionary<Enums.TriggerOptimizationReason, List<long>>();
List<OrderConsignee> insertOrderConsigneeList = new List<OrderConsignee>();
List<TimeLimitTask> insertTimeLimitTaskList = new List<TimeLimitTask>();
List<string> deleteTimeLimitTaskOrderIdList = new List<string>();
List<IUpdate<Model.Db.Order>> updateOrderList = new List<IUpdate<Model.Db.Order>>();
List<SkuTotalSaleInfo> insertSkuTotalSaleInfoList = new List<SkuTotalSaleInfo>();
IList<SkuTotalSaleInfo> updateSkuTotalSaleInfoList = new List<SkuTotalSaleInfo>();
List<SpuTotalSaleInfo> insertSpuTotalSaleInfoList = new List<SpuTotalSaleInfo>();
IList<SpuTotalSaleInfo> updateSpuTotalSaleInfoList = new List<SpuTotalSaleInfo>();
List<SpuOptimizationTask> insertSpuOptimizationTaskList = new List<SpuOptimizationTask>();
List<SkuOptimizationTask> insertSkuOptimizationTaskList = new List<SkuOptimizationTask>();
List<SpuOptimizationBargainTeamTask> insertSpuOptimizationBargainTeamTaskList = new List<SpuOptimizationBargainTeamTask>();
List<SpuOptimizationCompetitiveTenderTask> insertSpuOptimizationCompetitiveTenderTaskList = new List<SpuOptimizationCompetitiveTenderTask>();
//List<SpuOptimizationPurchaserCompetitiveTenderTask> insertSpuOptimizationPurchaserCompetitiveTenderTaskList = new List<SpuOptimizationPurchaserCompetitiveTenderTask>();
#endregion
//等待检查sku销量的订单集合
List<OP_OrderResponse> waitToCheckSkuSaleOrderList = new List<OP_OrderResponse>();
IDictionary<string, int> deductionSkuCountDictionary = new Dictionary<string, int>();
IDictionary<string, int> deductionSpuCountDictionary = new Dictionary<string, int>();
#region 同步订单
foreach (var qtOrder in qtOrderList.Items)
{
var dbOrder = dbOrderList.FirstOrDefault(o => o.Id == qtOrder.OrderId);
@ -184,10 +241,11 @@ namespace BBWYB.Server.Business.Sync
ProductId = qtOrderSku.ProductId,
BelongSkuId = belongSkus?.FirstOrDefault(j => j.Value<string>("SkuId") == qtOrderSku.SkuId)?.Value<string>("BelongSkuId") ?? string.Empty,
InPackAmount = qtOrderSku.PackAmount,
BuyerPayFreight = qtOrderSku.FreightAmount
BuyerPayFreight = qtOrderSku.FreightAmount,
IsNeedOptimization = 0,
IsOptimizationCompleted = 0
});
}
//收货人
insertOrderConsigneeList.Add(new OrderConsignee()
{
@ -202,25 +260,43 @@ namespace BBWYB.Server.Business.Sync
TelePhone = qtOrder.Consignee.Mobile,
Town = qtOrder.Consignee.Town
});
if (qtOrder.IsPay && !waitToCheckSkuSaleOrderList.Any(x => x.OrderId == qtOrder.OrderId))
waitToCheckSkuSaleOrderList.Add(qtOrder);
}
else
{
#region 订单状态脱离拳探 只处理付款和取消
Enums.OrderState? updateOrderState = null;
if (orderState == Enums.OrderState. && dbOrder.OrderState!=Enums.OrderState.)
if (orderState == Enums.OrderState. && dbOrder.OrderState != Enums.OrderState.)
{
//dbOrder.OrderState = Enums.OrderState.待付款;
updateOrderState = Enums.OrderState.;
}
if (dbOrder.OrderState == Enums.OrderState. && orderState != Enums.OrderState.)
if (dbOrder.OrderState == Enums.OrderState. && orderState != Enums.OrderState. && orderState != Enums.OrderState.)
{
updateOrderState = Enums.OrderState.;
if (!waitToCheckSkuSaleOrderList.Any(x => x.OrderId == qtOrder.OrderId))
waitToCheckSkuSaleOrderList.Add(qtOrder);
}
if (dbOrder.OrderState != Enums.OrderState. && orderState == Enums.OrderState.)
{
updateOrderState = Enums.OrderState.;
if (dbPurchaseTimeLimitTaskList.Any(t => t.OrderId == qtOrder.OrderId))
deleteTimeLimitTaskOrderIdList.Add(qtOrder.OrderId);
foreach (var qtOrderSku in qtOrder.OrderSkuList)
{
if (!deductionSkuCountDictionary.ContainsKey(qtOrderSku.SkuId))
deductionSkuCountDictionary.Add(qtOrderSku.SkuId, 0);
deductionSkuCountDictionary[qtOrderSku.SkuId] += qtOrderSku.Quantity;
if (!deductionSpuCountDictionary.ContainsKey(qtOrderSku.ProductId))
deductionSpuCountDictionary.Add(qtOrderSku.ProductId, 0);
deductionSpuCountDictionary[qtOrderSku.ProductId] += qtOrderSku.Quantity;
}
}
#endregion
@ -245,8 +321,324 @@ namespace BBWYB.Server.Business.Sync
}
}
}
#endregion
#region 统计销量
foreach (var qtOrder in waitToCheckSkuSaleOrderList)
{
foreach (var qtOrderSku in qtOrder.OrderSkuList)
{
#region 统计sku销量
{
var skuTotalSaleInfo = dbSkuTotalSaleInfoList.FirstOrDefault(s => s.SkuId == qtOrderSku.SkuId);
if (skuTotalSaleInfo == null)
{
skuTotalSaleInfo = insertSkuTotalSaleInfoList.FirstOrDefault(s => s.SkuId == qtOrderSku.SkuId);
if (skuTotalSaleInfo == null)
{
skuTotalSaleInfo = new SkuTotalSaleInfo()
{
SkuId = qtOrderSku.SkuId,
CreateTime = DateTime.Now,
IsEnabled = true,
ItemCount = 0,
ProductId = qtOrderSku.ProductId,
ShopId = shopId,
UpdateTime = DateTime.Now
};
insertSkuTotalSaleInfoList.Add(skuTotalSaleInfo);
}
}
else if (!updateSkuTotalSaleInfoList.Any(s => s.SkuId == qtOrderSku.SkuId))
{
updateSkuTotalSaleInfoList.Add(skuTotalSaleInfo);
}
skuTotalSaleInfo.ItemCount += qtOrderSku.Quantity;
}
#endregion
#region 统计spu销量
{
var spuTotalSaleInfo = dbSpuTotalSaleInfoList.FirstOrDefault(s => s.ProductId == qtOrderSku.ProductId);
if (spuTotalSaleInfo == null)
{
spuTotalSaleInfo = insertSpuTotalSaleInfoList.FirstOrDefault(s => s.ProductId == qtOrderSku.ProductId);
if (spuTotalSaleInfo == null)
{
spuTotalSaleInfo = new SpuTotalSaleInfo()
{
CreateTime = DateTime.Now,
IsEnabled = true,
ItemCount = 0,
ProductId = qtOrderSku.ProductId,
ShopId = shopId,
UpdateTime = DateTime.Now,
LastOptimizationItemCount = 0
};
insertSpuTotalSaleInfoList.Add(spuTotalSaleInfo);
}
}
else if (!updateSpuTotalSaleInfoList.Any(s => s.ProductId == qtOrderSku.ProductId))
{
updateSpuTotalSaleInfoList.Add(spuTotalSaleInfo);
}
spuTotalSaleInfo.ItemCount += qtOrderSku.Quantity;
}
#endregion
}
}
#endregion
#region 检查待议价任务
{
if (waitToCheckSkuSaleOrderList.Count() > 0)
{
var spuIdList = waitToCheckSkuSaleOrderList.SelectMany(o => o.OrderSkuList.Select(osku => osku.ProductId)).Distinct().ToList();
//没有完成首次采购的spu
var noFisrstPurchasedSpuList = dbSpuTotalSaleInfoList.Union(insertSpuTotalSaleInfoList)
.Where(s => s.IsFirstPurchaseCompleted == false)
.Select(s => s.ProductId)
.ToList();
//查询已存在未结束的优化任务
var dbSpuOptimizationTaskList = fsql.Select<SpuOptimizationTask>()
.Where(t => t.ShopId == shopId &&
t.IsOptimizationCompleted == false &&
spuIdList.Contains(t.ProductId))
.ToList();
if (noFisrstPurchasedSpuList.Count() > 0)
{
var bargainTeamList = venderBusiness.GetYiJiaGroup(); //获取议价组
var shopList = venderBusiness.GetShopList(platform: Enums.Platform.);
var bargainTeamIdList = bargainTeamList.Select(t => t.Id).ToList();
var waitToCompetitiveTenderSchemeList = fsql.Select<PurchaseScheme>()
.Where(ps => bargainTeamIdList.Contains(ps.BelongBargainTeamId) &&
spuIdList.Contains(ps.ProductId))
.ToList(); //需要参与竞标采购方案
var waitToCompetitiveTenderSchemeIdList = waitToCompetitiveTenderSchemeList.Select(ps => ps.Id).ToList();
var waitToCompetitiveTenderSchemePurchaserList = fsql.Select<PurchaseSchemeProduct>()
.Where(psp => waitToCompetitiveTenderSchemeIdList.Contains(psp.SkuPurchaseSchemeId))
.GroupBy(psp => new { psp.SkuPurchaseSchemeId, psp.PurchaserId })
.ToList(g => new { g.Key.SkuPurchaseSchemeId, g.Key.PurchaserId }); //需要参与竞标的采购商
var waitToCheckOrderSpuGroups = waitToCheckSkuSaleOrderList.SelectMany(o => o.OrderSkuList).GroupBy(osku => osku.ProductId);
foreach (var spuGroup in waitToCheckOrderSpuGroups)
{
if (noFisrstPurchasedSpuList.Contains(spuGroup.Key) &&
!dbSpuOptimizationTaskList.Any(t => t.ProductId == spuGroup.Key) &&
!insertSpuOptimizationTaskList.Any(t => t.ProductId == spuGroup.Key))
{
var includeSpuOrderList = waitToCheckSkuSaleOrderList.Where(o => o.OrderSkuList.Any(osku => osku.ProductId == spuGroup.Key));
var sourceShopName = string.Empty;
long sourceShopId = 0;
//拳探sku-京东sku下单关系映射表
var mappingQT_JDSKUDictionary = new Dictionary<string, string>();
#region 解析来源店铺数据
foreach (var waitCheckOrder in includeSpuOrderList)
{
if (!string.IsNullOrEmpty(waitCheckOrder.Extended))
{
try
{
var jobject = JObject.Parse(waitCheckOrder.Extended);
sourceShopName = jobject.Value<string>("SourceShopName");
if (jobject.ContainsKey("BelongSkus"))
{
var jbelongSkus = jobject["BelongSkus"] as JArray;
foreach (var j in jbelongSkus)
{
var skuId = j.Value<string>("SkuId");
var belongSkuId = j.Value<string>("BelongSkuId");
if (!mappingQT_JDSKUDictionary.ContainsKey(skuId))
mappingQT_JDSKUDictionary.TryAdd(skuId, belongSkuId);
}
}
}
catch (Exception ex)
{
}
}
}
if (!string.IsNullOrEmpty(sourceShopName))
{
var belongShop = shopList.FirstOrDefault(s => s.ShopName == sourceShopName);
if (belongShop != null)
sourceShopId = long.Parse(belongShop.ShopId);
}
#endregion
#region 读取JDSKU预估金额
var jdskus = mappingQT_JDSKUDictionary.Values.ToList();
var jdskuRecentCostList = fsqlManager.BBWYCfsql.Select<SkuRecentCost>(jdskus).ToList();
#endregion
#region 处理SKU分组
var skuGroups = spuGroup.GroupBy(osku => osku.SkuId).ToList();
var skuIdList = skuGroups.Select(g => g.Key).ToList();
#endregion
#region 创建SPU优化任务
var spuOptimizationTask = new SpuOptimizationTask()
{
Id = idGenerator.NewLong(),
BelongShopId = sourceShopId,
BelongShopName = sourceShopName,
CompletionTime = null,
CreateTime = DateTime.Now,
IsOptimizationCompleted = false,
LastOptimizationTime = null,
ProductId = spuGroup.Key,
ShopId = shopId,
ProductTitle = SubstringProductTitleFromSku(spuGroup.FirstOrDefault()?.ProductTitle),
TriggerOptimizationReason = Enums.TriggerOptimizationReason.,
PreSkuCount = skuGroups.Count(),
PreItemCount = 0,
PrePurchaseAmount = 0M
};
insertSpuOptimizationTaskList.Add(spuOptimizationTask);
#endregion
#region 创建SKU优化任务
foreach (var skuGroup in skuGroups)
{
mappingQT_JDSKUDictionary.TryGetValue(skuGroup.Key, out string jdSkuId);
var preItemCount = skuGroup.Sum(osku => osku.Quantity);
var prePurchaseAmount = 0M;
if (!string.IsNullOrEmpty(jdSkuId))
{
var jdSkuRecentCost = jdskuRecentCostList.FirstOrDefault(x => x.SkuId == jdSkuId);
if (jdSkuRecentCost != null)
{
prePurchaseAmount = (jdSkuRecentCost.SingleSkuAmount ?? 0M +
jdSkuRecentCost.SingleFirstFreight ?? 0M +
jdSkuRecentCost.SingleFreight ?? 0M +
jdSkuRecentCost.SingleDeliveryFreight ?? 0M +
jdSkuRecentCost.SingleConsumableAmount ?? 0M +
jdSkuRecentCost.SingleInStorageAmount ?? 0M +
jdSkuRecentCost.SingleOutStorageAmount ?? 0M +
jdSkuRecentCost.SinglePackagingLaborAmount ?? 0M +
jdSkuRecentCost.SingleOperationAmount ?? 0M) * preItemCount;
}
}
var skuOptimizationTask = new SkuOptimizationTask()
{
Id = idGenerator.NewLong(),
CreateTime = DateTime.Now,
JDSkuId = jdSkuId,
PreItemCount = preItemCount,
SkuId = skuGroup.Key,
SpuOptimizationTaskId = spuOptimizationTask.Id,
PrePurchaseAmount = prePurchaseAmount
};
insertSkuOptimizationTaskList.Add(skuOptimizationTask);
//累计spu优化任务信息
spuOptimizationTask.PreItemCount += preItemCount;
spuOptimizationTask.PrePurchaseAmount += prePurchaseAmount;
}
#endregion
#region 创建SPU优化议价组任务
foreach (var department in bargainTeamList)
{
var spuOptimizationBargainTeamTask = new SpuOptimizationBargainTeamTask()
{
Id = idGenerator.NewLong(),
BelongTeamId = department.Id,
BelongTeamName = department.DepartmentName,
CompletionTime = null,
IsOptimizationCompleted = false,
SpuOptimizationTaskId = spuOptimizationTask.Id
};
insertSpuOptimizationBargainTeamTaskList.Add(spuOptimizationBargainTeamTask);
#region 创建采购方案竞标任务
var waitJoinSchemeList = waitToCompetitiveTenderSchemeList.Where(ps => ps.BelongBargainTeamId == department.Id &&
skuIdList.Contains(ps.SkuId))
.ToList();
//var waitJoinSchemeIdList = waitJoinSchemeList.Select(ps => ps.Id).ToList();
//var waitJonPurchaserList = waitToCompetitiveTenderSchemePurchaserList.Where(x => waitJoinSchemeIdList.Contains(x.SkuPurchaseSchemeId));
if (waitJoinSchemeList.Count() > 0)
{
insertSpuOptimizationCompetitiveTenderTaskList.AddRange(waitJoinSchemeList.Select(ps => new SpuOptimizationCompetitiveTenderTask()
{
Id = idGenerator.NewLong(),
BargainTeamId = ps.BelongBargainTeamId,
CreateTime = DateTime.Now,
IsUpdateQuotedPrice = false,
SchemeGroupId = ps.SchemeGroupId,
SchemeId = ps.Id,
SkuId = ps.SkuId,
SpuOptimizationBargainTeamTaskId = spuOptimizationBargainTeamTask.Id,
SpuOptimizationTaskId = spuOptimizationTask.Id,
UpdateTime = DateTime.Now
}));
//insertSpuOptimizationPurchaserCompetitiveTenderTaskList.AddRange(waitJonPurchaserList.Select(x =>
//{
// var ps = waitJoinSchemeList.FirstOrDefault(ps => ps.Id == x.SkuPurchaseSchemeId);
// return new SpuOptimizationPurchaserCompetitiveTenderTask()
// {
// Id = idGenerator.NewLong(),
// BargainTeamId = ps.BelongBargainTeamId,
// CreateTime = DateTime.Now,
// UpdateTime = DateTime.Now,
// IsUpdateQuotedPrice = false,
// PurchaserId = x.PurchaserId,
// SchemeGroupId = ps.SchemeGroupId,
// SchemeId = ps.Id,
// SkuId = ps.SkuId,
// SpuOptimizationTaskId = spuOptimizationTask.Id
// };
//}));
}
#endregion
}
#endregion
#region 创建优化限时任务
{
//判断sku是否首次采购
//var isFirst = !dbSpuTotalSaleInfoList.Any(s => s.ProductId == spuGroup.Key);
insertTimeLimitTaskList.Add(new TimeLimitTask()
{
Id = idGenerator.NewLong(),
CreateTme = DateTime.Now,
//ExpirationTime = DateTime.Now.AddDays(isFirst ? 2 : 1),
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now),
//OrderId = o.OrderId,
//OrderSn = o.OrderSn,
ShopId = shopId,
//SkuId = waitCheckOrderSku.SkuId,
TaskType = Enums.TimeLimitTaskType.,
TaskId = spuOptimizationTask.Id,
Remark = "首次采购限时任务"
});
}
#endregion
}
}
}
}
}
#endregion
#region 检查限时采购任务
CheckPurchaseTimeLimitTask(shopId, qtOrderList.Items, dbPurchaseTimeLimitTaskList, insertTimeLimitTaskList);
#endregion
fsql.Transaction(() =>
{
@ -262,12 +654,49 @@ namespace BBWYB.Server.Business.Sync
if (insertTimeLimitTaskList.Count() > 0)
fsql.Insert(insertTimeLimitTaskList).ExecuteAffrows();
if (insertSpuOptimizationTaskList.Count() > 0)
fsql.Insert(insertSpuOptimizationTaskList).ExecuteAffrows();
if (insertSkuOptimizationTaskList.Count() > 0)
fsql.Insert(insertSkuOptimizationTaskList).ExecuteAffrows();
if (insertSpuOptimizationBargainTeamTaskList.Count() > 0)
fsql.Insert(insertSpuOptimizationBargainTeamTaskList).ExecuteAffrows();
if (insertSpuOptimizationCompetitiveTenderTaskList.Count() > 0)
fsql.Insert(insertSpuOptimizationCompetitiveTenderTaskList).ExecuteAffrows();
//if (insertSpuOptimizationPurchaserCompetitiveTenderTaskList.Count() > 0)
// fsql.Insert(insertSpuOptimizationPurchaserCompetitiveTenderTaskList).ExecuteAffrows();
if (updateOrderList.Count() > 0)
foreach (var update in updateOrderList)
update.ExecuteAffrows();
if (deleteTimeLimitTaskOrderIdList.Count() > 0)
fsql.Delete<TimeLimitTask>().Where(t => deleteTimeLimitTaskOrderIdList.Contains(t.OrderId)).ExecuteAffrows();
if (insertSkuTotalSaleInfoList.Count() > 0)
fsql.Insert(insertSkuTotalSaleInfoList).ExecuteAffrows();
if (updateSkuTotalSaleInfoList.Count() > 0)
{
foreach (var item in updateSkuTotalSaleInfoList)
fsql.Update<SkuTotalSaleInfo>(item.SkuId).Set(s => s.ItemCount, item.ItemCount)
.Set(s => s.UpdateTime, DateTime.Now)
.ExecuteAffrows();
}
if (insertSpuTotalSaleInfoList.Count() > 0)
fsql.Insert(insertSpuTotalSaleInfoList).ExecuteAffrows();
if (updateSpuTotalSaleInfoList.Count() > 0)
{
foreach (var item in updateSpuTotalSaleInfoList)
fsql.Update<SpuTotalSaleInfo>(item.ProductId).Set(s => s.ItemCount, item.ItemCount)
.Set(s => s.UpdateTime, DateTime.Now)
.ExecuteAffrows();
}
foreach (var key in deductionSkuCountDictionary.Keys)
fsql.Update<SkuTotalSaleInfo>(key).Set(s => s.ItemCount - deductionSkuCountDictionary[key]).ExecuteAffrows();
foreach (var key in deductionSpuCountDictionary.Keys)
fsql.Update<SpuTotalSaleInfo>(key).Set(s => s.ItemCount - deductionSpuCountDictionary[key]).ExecuteAffrows();
});
}
catch (Exception ex)
@ -276,6 +705,13 @@ namespace BBWYB.Server.Business.Sync
}
}
/// <summary>
/// 检查限时采购任务
/// </summary>
/// <param name="shopId"></param>
/// <param name="orderList"></param>
/// <param name="dbTimeLimits"></param>
/// <param name="insertTimeLimitTasks"></param>
private void CheckPurchaseTimeLimitTask(long shopId, IList<OP_OrderResponse> orderList, IList<TimeLimitTask> dbTimeLimits, List<TimeLimitTask> insertTimeLimitTasks)
{
foreach (var order in orderList)
@ -292,7 +728,7 @@ namespace BBWYB.Server.Business.Sync
SkuId = osku.SkuId,
TaskType = Enums.TimeLimitTaskType.,
ShopId = shopId,
ExpirationTime = CalculationPurcashTimeLimitTaskExpirationTime(order.PayTime.Value),
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., order.PayTime.Value),
PayTime = order.PayTime
}).ToList();
if (waitInserTimeLimitTasks != null && waitInserTimeLimitTasks.Count() > 0)
@ -355,5 +791,25 @@ namespace BBWYB.Server.Business.Sync
return Enums.OrderState.;
return null;
}
public Enums.TriggerOptimizationReason? GetOptimizationReason(SpuTotalSaleInfo s)
{
if (s.IsFirstPurchaseCompleted == false)
return Enums.TriggerOptimizationReason.;
if (s.IsFirstPurchaseCompleted == true &&
s.IsFirstOptimizationCompleted == false &&
s.ItemCount - s.FirstPurchaseCompletedItemCount >= 20)
return Enums.TriggerOptimizationReason.;
if (s.IsFirstOptimizationCompleted == true && s.LastOptimizationItemCount != 0 && s.ItemCount * 1.0 / s.LastOptimizationItemCount >= 2)
return Enums.TriggerOptimizationReason.;
return null;
}
private string SubstringProductTitleFromSku(string productTitle)
{
if (!string.IsNullOrEmpty(productTitle) && productTitle.Contains(" "))
productTitle = productTitle.Substring(0, productTitle.LastIndexOf(" "));
return productTitle;
}
}
}

515
BBWYB.Server.Business/Sync/ProductSyncBusiness.cs

@ -0,0 +1,515 @@
using BBWYB.Common.Log;
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Dto;
using FreeSql;
using SDKAdapter.OperationPlatform.Models;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business.Sync
{
public class ProductSyncBusiness : BaseBusiness, IDenpendency
{
private ProductBusiness productBusiness;
private VenderBusiness venderBusiness;
private TaskSchedulerManager taskSchedulerManager;
public ProductSyncBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, ProductBusiness productBusiness, VenderBusiness venderBusiness, TaskSchedulerManager taskSchedulerManager) : base(fsql, nLogManager, idGenerator)
{
this.productBusiness = productBusiness;
this.venderBusiness = venderBusiness;
this.taskSchedulerManager = taskSchedulerManager;
}
/// <summary>
/// 同步所有店铺的全部产品
/// </summary>
public void SyncAllShopAllProduct()
{
var shopList = venderBusiness.GetShopList(platform: Enums.Platform.);
//var shopList = venderBusiness.GetShopList(shopId: 9);
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncProduct(shop, true), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncProductTaskScheduler);
}
}
public void SyncAllShopUpdateProduct()
{
var shopList = venderBusiness.GetShopList(platform: Enums.Platform.);
//var shopList = venderBusiness.GetShopList(shopId: 9);
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncUpdateProduct(shop), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncProductTaskScheduler);
}
}
public void SyncOneShopUpdateProduct(long shopId)
{
var shopList = venderBusiness.GetShopList(shopId, platform: Enums.Platform.);
foreach (var shop in shopList)
{
Task.Factory.StartNew(() => SyncUpdateProduct(shop), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncProductTaskScheduler);
}
}
private void SyncProduct(ShopResponse shop, bool IsSyncAllProduct = false)
{
try
{
var shopId = long.Parse(shop.ShopId);
var dbProductList = fsql.Select<Product>().Where(p => p.ShopId == shopId).ToList();
var dbProductSkuList = fsql.Select<ProductSku>().Where(p => p.ShopId == shopId).ToList();
List<OP_ProductResponse> productList = new List<OP_ProductResponse>();
List<OP_ProductSkuResponse> productSkuList = new List<OP_ProductSkuResponse>();
List<Product> insertProductList = new List<Product>();
List<ProductSku> insertProductSkuList = new List<ProductSku>();
List<IUpdate<Product>> updateProductList = new List<IUpdate<Product>>();
List<IUpdate<ProductSku>> updateProductSkuList = new List<IUpdate<ProductSku>>();
var request = new OP_QueryProductRequest()
{
PageSize = 50,
PageIndex = 1,
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
Platform = SDKAdapter.AdapterEnums.PlatformType.
};
var requestSku = new OP_QueryProductSkuRequest()
{
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
Platform = SDKAdapter.AdapterEnums.PlatformType.,
//Spu = product.Id,
PageSize = 50,
PageIndex = 1
};
while (true)
{
Console.WriteLine($"{shop.ShopName} 获取第{request.PageIndex}页产品");
var pListRes = productBusiness.GetProductList(request);
if (pListRes == null || pListRes.Items == null || pListRes.Items.Count == 0)
break;
productList.AddRange(pListRes.Items);
foreach (var product in pListRes.Items)
{
requestSku.Spu = product.Id;
var psListRes = productBusiness.GetProductSkuList(requestSku);
if (psListRes == null || psListRes.Items == null || psListRes.Items.Count == 0)
continue;
productSkuList.AddRange(psListRes.Items);
}
if (pListRes.Items.Count < 50 || !IsSyncAllProduct)
break;
request.PageIndex++;
Thread.Sleep(1000);
}
#region 找出新增的产品
var newProductList = productList.Where(p => !dbProductList.Any(dp => dp.Id == p.Id)).ToList();
if (newProductList.Count() > 0)
{
insertProductList.AddRange(newProductList.Select(p => new Product()
{
Id = p.Id,
Logo = p.Logo,
ProductName = p.Title,
ShopId = int.Parse(shop.ShopId),
State = p.State,
SyncTime = DateTime.Now,
UpdateTime = DateTime.Now,
UpperTime = p.CreateTime,
CategoryId = p.CategoryId,
CategoryName = p.CategoryName
}));
}
#endregion
#region 找出变化的产品 (状态,标题)
var stateChangeProductList = productList.Where(p => dbProductList.Any(dp => dp.Id == p.Id &&
(dp.State != p.State ||
dp.ProductName != p.Title ||
dp.CategoryId != p.CategoryId))).ToList();
if (stateChangeProductList.Count() > 0)
{
foreach (var product in stateChangeProductList)
{
var update = fsql.Update<Product>(product.Id).Set(p => p.State, product.State)
.Set(p => p.ProductName, product.Title)
.Set(p => p.CategoryId, product.CategoryId)
.Set(p => p.CategoryName, product.CategoryName);
updateProductList.Add(update);
}
}
#endregion
#region 找出接口查不出的产品
var goneProductList = dbProductList.Where(dp => !productList.Any(p => p.Id == dp.Id)).ToList();
if (goneProductList.Count() > 0)
{
var goneProductIdList = goneProductList.Select(p => p.Id).ToList();
var update = fsql.Update<Product>().Set(p => p.State, 0).Where(p => goneProductIdList.Contains(p.Id));
updateProductList.Add(update);
}
#endregion
#region 找出新增的SKU
var newProductSkuList = productSkuList.Where(ps => !dbProductSkuList.Any(dps => dps.Id == ps.Id)).ToList();
if (newProductSkuList.Count() > 0)
{
insertProductSkuList.AddRange(newProductSkuList.Select(ps => new ProductSku()
{
Id = ps.Id,
Logo = ps.Logo,
Price = ps.Price,
ProductId = ps.ProductId,
ShopId = int.Parse(shop.ShopId),
SkuName = ps.Title,
State = ps.State,
SyncTime = DateTime.Now,
UpdateTime = DateTime.Now,
UpperTime = ps.CreateTime,
CategoryId = ps.CategoryId,
CategoryName = ps.CategoryName
}));
}
#endregion
#region 找出状态变化的SKU
var stateChangeProductSkuList = productSkuList.Where(ps => dbProductSkuList.Any(dps => dps.Id == ps.Id &&
(dps.State != ps.State ||
dps.SkuName != ps.Title ||
dps.Price != ps.Price ||
dps.Logo != ps.Logo ||
dps.CategoryId != ps.CategoryId))).ToList();
if (stateChangeProductSkuList.Count() > 0)
{
foreach (var productSku in stateChangeProductSkuList)
{
var update = fsql.Update<ProductSku>(productSku.Id).Set(p => p.State, productSku.State)
.Set(p => p.SkuName, productSku.Title)
.Set(p => p.Price, productSku.Price)
.Set(p => p.Logo, productSku.Logo)
.Set(p => p.CategoryId, productSku.CategoryId)
.Set(p => p.CategoryName, productSku.CategoryName);
updateProductSkuList.Add(update);
}
}
#endregion
#region 找出接口查不出的SKU
var goneProductSkuList = dbProductSkuList.Where(dps => !productSkuList.Any(ps => ps.Id == dps.Id)).ToList();
if (goneProductSkuList.Count() > 0)
{
var goneProductSkuIdList = goneProductSkuList.Select(ps => ps.Id).ToList();
var update = fsql.Update<ProductSku>().Set(ps => ps.State, 0).Where(ps => goneProductSkuIdList.Contains(ps.Id));
updateProductSkuList.Add(update);
}
#endregion
fsql.Transaction(() =>
{
if (insertProductList.Count() > 0)
fsql.Insert(insertProductList).ExecuteAffrows();
if (insertProductSkuList.Count() > 0)
fsql.Insert(insertProductSkuList).ExecuteAffrows();
});
{
var tempUpdateList = new List<IUpdate<Product>>();
if (updateProductList.Count() > 0)
{
for (var i = 0; i < updateProductList.Count(); i++)
{
tempUpdateList.Add(updateProductList[i]);
if (tempUpdateList.Count() == 20)
{
fsql.Transaction(() =>
{
foreach (var update in tempUpdateList)
update.ExecuteAffrows();
});
tempUpdateList.Clear();
}
}
if (tempUpdateList.Count() > 0)
{
fsql.Transaction(() =>
{
foreach (var update in tempUpdateList)
update.ExecuteAffrows();
});
tempUpdateList.Clear();
updateProductList.Clear();
}
}
}
{
var tempUpdateList = new List<IUpdate<ProductSku>>();
if (updateProductSkuList.Count() > 0)
{
for (var i = 0; i < updateProductSkuList.Count(); i++)
{
tempUpdateList.Add(updateProductSkuList[i]);
if (tempUpdateList.Count() == 20)
{
fsql.Transaction(() =>
{
foreach (var update in tempUpdateList)
update.ExecuteAffrows();
});
tempUpdateList.Clear();
}
}
if (tempUpdateList.Count() > 0)
{
fsql.Transaction(() =>
{
foreach (var update in tempUpdateList)
update.ExecuteAffrows();
});
tempUpdateList.Clear();
updateProductSkuList.Clear();
}
}
}
Console.WriteLine($"{shop.ShopName}同步完毕,新增spu{insertProductList.Count()}个,新增sku{insertProductSkuList.Count()}个,更新spu{updateProductList.Count()}个,更新sku{updateProductSkuList.Count()}个");
}
catch (Exception ex)
{
nLogManager.Default().Error(ex, $"SyncProduct ShopId:{shop.ShopName}");
}
}
private void SyncUpdateProduct(ShopResponse shop)
{
try
{
List<Product> dbProductList;
List<ProductSku> dbProductSkuList;
List<OP_ProductResponse> opProductList = new List<OP_ProductResponse>();
List<OP_ProductSkuResponse> opProductSkuList = new List<OP_ProductSkuResponse>();
List<Product> insertProductList = new List<Product>();
List<ProductSku> insertProductSkuList = new List<ProductSku>();
List<IUpdate<Product>> updateProductList = new List<IUpdate<Product>>();
List<IUpdate<ProductSku>> updateProductSkuList = new List<IUpdate<ProductSku>>();
#region 查询变化的spu
{
#region 上架的spu
var spuRequest = new OP_QueryProductRequest()
{
PageSize = 50,
PageIndex = 1,
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
Platform = SDKAdapter.AdapterEnums.PlatformType.,
//Spu = "9985",
UpdateStartTime = DateTime.Now.AddHours(-1), //DateTime.Parse("2024-04-02 12:00:00") DateTime.Now.AddHours(-1),
UpdateEndTime = DateTime.Now //DateTime.Parse("2024-04-02 12:02:00") DateTime.Now
};
while (true)
{
var response = productBusiness.GetProductList(spuRequest);
if (response == null || response.Items == null || response.Items.Count == 0)
break;
opProductList.AddRange(response.Items);
if (response.Items.Count < spuRequest.PageSize)
break;
spuRequest.PageIndex++;
}
#endregion
#region 下架的spu
spuRequest.PageIndex = 1;
spuRequest.ProductState = SDKAdapter.AdapterEnums.ProuctState.;
while (true)
{
var response = productBusiness.GetProductList(spuRequest);
if (response == null || response.Items == null || response.Items.Count == 0)
break;
opProductList.AddRange(response.Items);
if (response.Items.Count < spuRequest.PageSize)
break;
spuRequest.PageIndex++;
}
#endregion
}
#endregion
#region 对比spu
var spuIdList = opProductList.Select(x => x.Id);
dbProductList = fsql.Select<Product>(spuIdList).ToList();
#region 找出新增的产品
var newProductList = opProductList.Where(p => !dbProductList.Any(dp => dp.Id == p.Id)).ToList();
if (newProductList.Count() > 0)
{
insertProductList.AddRange(newProductList.Select(p => new Product()
{
Id = p.Id,
Logo = p.Logo,
ProductName = p.Title,
ShopId = int.Parse(shop.ShopId),
State = p.State,
SyncTime = DateTime.Now,
UpdateTime = p.UpdateTime,
UpperTime = p.CreateTime,
CategoryId = p.CategoryId,
CategoryName = p.CategoryName
}));
}
#endregion
#region 找出变化的产品 (状态,标题,类目)
var stateChangeProductList = opProductList.Where(p => dbProductList.Any(dp => dp.Id == p.Id &&
(dp.State != p.State ||
dp.ProductName != p.Title ||
dp.CategoryId != p.CategoryId))).ToList();
if (stateChangeProductList.Count() > 0)
{
foreach (var product in stateChangeProductList)
{
var update = fsql.Update<Product>(product.Id).Set(p => p.State, product.State)
.Set(p => p.ProductName, product.Title)
.Set(p => p.CategoryId, product.CategoryId)
.Set(p => p.CategoryName, product.CategoryName)
.Set(p => p.UpdateTime, product.UpdateTime);
updateProductList.Add(update);
}
}
#endregion
#endregion
#region 对比sku
foreach (var product in opProductList)
{
var skuRequest = new OP_QueryProductSkuRequest()
{
AppKey = shop.AppKey,
AppSecret = shop.AppSecret,
AppToken = shop.AppToken,
Platform = SDKAdapter.AdapterEnums.PlatformType.,
Spu = product.Id,
PageSize = 50,
PageIndex = 1,
};
var response = productBusiness.GetProductSkuList(skuRequest);
if (response == null || response.Items == null || response.Items.Count == 0)
continue;
opProductSkuList.AddRange(response.Items);
}
var skuIdList = opProductSkuList.Select(x => x.Id);
dbProductSkuList = fsql.Select<ProductSku>(skuIdList).ToList();
#region 找出新增的SKU
var newProductSkuList = opProductSkuList.Where(ps => !dbProductSkuList.Any(dps => dps.Id == ps.Id)).ToList();
if (newProductSkuList.Count() > 0)
{
insertProductSkuList.AddRange(newProductSkuList.Select(ps => new ProductSku()
{
Id = ps.Id,
Logo = ps.Logo,
Price = ps.Price,
ProductId = ps.ProductId,
ShopId = int.Parse(shop.ShopId),
SkuName = ps.Title,
State = ps.State,
SyncTime = DateTime.Now,
UpdateTime = DateTime.Now,
UpperTime = ps.CreateTime,
CategoryId = ps.CategoryId,
CategoryName = ps.CategoryName
}));
}
#endregion
#region 找出状态变化的SKU
var stateChangeProductSkuList = opProductSkuList.Where(ps => dbProductSkuList.Any(dps => dps.Id == ps.Id &&
(dps.State != ps.State ||
dps.SkuName != ps.Title ||
dps.Price != ps.Price ||
dps.Logo != ps.Logo ||
dps.CategoryId != ps.CategoryId))).ToList();
if (stateChangeProductSkuList.Count() > 0)
{
foreach (var productSku in stateChangeProductSkuList)
{
var update = fsql.Update<ProductSku>(productSku.Id).Set(p => p.State, productSku.State)
.Set(p => p.SkuName, productSku.Title)
.Set(p => p.Price, productSku.Price)
.Set(p => p.Logo, productSku.Logo)
.Set(p => p.CategoryId, productSku.CategoryId)
.Set(p => p.CategoryName, productSku.CategoryName);
updateProductSkuList.Add(update);
}
}
#endregion
#region 找出接口查不出的SKU
var goneProductSkuList = dbProductSkuList.Where(dps => !opProductSkuList.Any(ps => ps.Id == dps.Id)).ToList();
if (goneProductSkuList.Count() > 0)
{
var goneProductSkuIdList = goneProductSkuList.Select(ps => ps.Id).ToList();
var update = fsql.Update<ProductSku>().Set(ps => ps.State, 0).Where(ps => goneProductSkuIdList.Contains(ps.Id));
updateProductSkuList.Add(update);
}
#endregion
#endregion
#region 数据库操作
fsql.Transaction(() =>
{
if (insertProductList.Count() > 0)
fsql.Insert(insertProductList).ExecuteAffrows();
if (insertProductSkuList.Count() > 0)
fsql.Insert(insertProductSkuList).ExecuteAffrows();
if (updateProductList.Count() > 0)
{
foreach (var update in updateProductList)
update.ExecuteAffrows();
}
if (updateProductSkuList.Count() > 0)
{
foreach (var update in updateProductSkuList)
update.ExecuteAffrows();
}
});
#endregion
}
catch (Exception ex)
{
nLogManager.Default().Error(ex, $"SyncProduct ShopId:{shop.ShopName}");
}
}
}
}

7
BBWYB.Server.Business/TaskSchedulerManager.cs

@ -4,15 +4,22 @@ namespace BBWYB.Server.Business
{
public class TaskSchedulerManager
{
public LimitedConcurrencyLevelTaskScheduler SyncProductTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler SyncOrderTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler PurchaseOrderCallbackTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler AggregationPurchaserTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler OptimizationTaskScheduler { get; private set; }
public TaskSchedulerManager()
{
SyncOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
PurchaseOrderCallbackTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
SyncProductTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
AggregationPurchaserTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(1);
OptimizationTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(3);
}
}
}

298
BBWYB.Server.Business/TimeLimitTask/TimeLimitRules.cs

@ -0,0 +1,298 @@
using BBWYB.Common.Models;
using BBWYB.Server.Model;
namespace BBWYB.Server.Business
{
public class TimeLimitRules : IDenpendency
{
/// <summary>
/// 计算到期时间算法字典
/// </summary>
private IDictionary<Enums.TimeLimitTaskType, Func<DateTime, DateTime>> calculateExpirationTimeAlgorithmDictionary;
public TimeLimitRules()
{
calculateExpirationTimeAlgorithmDictionary = new Dictionary<Enums.TimeLimitTaskType, Func<DateTime, DateTime>>()
{
{ Enums.TimeLimitTaskType., CalculateExpirationTimeFor5WorkHour },
{ Enums.TimeLimitTaskType., CalculateExpirationTimeFor8WorkHour },
{ Enums.TimeLimitTaskType., CalculateExpirationTimeFor8WorkHour },
{ Enums.TimeLimitTaskType., CalculateExpirationTimeFor8WorkHour },
{ Enums.TimeLimitTaskType., CalculateExpirationTimeFor2WorkHour }
};
}
/// <summary>
/// 计算到期时间
/// </summary>
/// <param name="timeLimitTaskType">任务类型</param>
/// <param name="startTime">起点计算时间</param>
/// <returns></returns>
public DateTime CalculateExpirationTime(Enums.TimeLimitTaskType timeLimitTaskType, DateTime startTime)
{
return calculateExpirationTimeAlgorithmDictionary[timeLimitTaskType](startTime);
}
/// <summary>
/// 计算需要追加的天数,周六追加2天,周日追加1天
/// </summary>
/// <param name="dayOfWeek"></param>
/// <returns></returns>
private int CalculateAddDay(DayOfWeek dayOfWeek)
{
if (dayOfWeek == DayOfWeek.Saturday)
return 2;
return 1;
}
/// <summary>
/// 8小时工作时计算到期时间
/// </summary>
/// <param name="startTime">起点时间</param>
/// <returns></returns>
private DateTime CalculateExpirationTimeFor8WorkHour(DateTime startTime)
{
int addDay = 0, addHour = 0, addSeconds = 0;
//先确定是否为周日
if (startTime.DayOfWeek == DayOfWeek.Sunday)
{
addDay = 1;
addHour = 18;
}
else
{
if (startTime.Hour < 9)
addHour = 18;
else if (startTime.Hour >= 9 && startTime.Hour < 12)
{
//计算从起点时间的9点开始到当前时间的时差
var timeSpan = startTime - startTime.Date.AddHours(9);
if (timeSpan.TotalMinutes <= 5)
{
//从9点开始小于5分钟以内,以当天18点结束
addHour = 18;
}
else
{
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 9;
addSeconds = (int)timeSpan.TotalSeconds;
}
}
else if (startTime.Hour >= 12 && startTime.Hour < 13)
{
//下一个工作日的12点结束
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 12;
}
else if (startTime.Hour >= 13 && startTime.Hour < 18)
{
var timeSpan = startTime - startTime.Date.AddHours(13);
//到下一个工作日的当前时间结束
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 13;
addSeconds = (int)timeSpan.TotalSeconds;
}
else if (startTime.Hour >= 18)
{
//下一个工作日的18点结束
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 18;
}
}
return startTime.Date.AddDays(addDay).AddHours(addHour).AddSeconds(addSeconds);
}
/// <summary>
/// 2小时工作时计算到期时间
/// </summary>
/// <param name="startTime">起点时间</param>
/// <returns></returns>
private DateTime CalculateExpirationTimeFor2WorkHour(DateTime startTime)
{
int addDay = 0, addHour = 0, addSeconds = 0;
//先确定是否为周日
if (startTime.DayOfWeek == DayOfWeek.Sunday)
{
addDay = 1;
addHour = 11;
}
else
{
if (startTime.Hour < 9)
addHour = 11;
else if (startTime.Hour >= 9 && startTime.Hour < 12)
{
//如果在10点钟以前,则加两个小时
if (startTime.Hour < 10)
{
addHour = 11;
addSeconds = Convert.ToInt32((startTime - startTime.Date.AddHours(9)).TotalSeconds);
}
else
{
addHour = 13;
var to12senconds = Convert.ToInt32((startTime.Date.AddHours(12) - startTime).TotalSeconds);
addSeconds = 7200 - to12senconds;
}
}
else if (startTime.Hour >= 12 && startTime.Hour < 13)
{
addHour = 15;
}
else if (startTime.Hour >= 13 && startTime.Hour < 18)
{
if (startTime.Hour < 16)
{
addHour = startTime.Hour + 2;
addSeconds = startTime.Minute * 60 + startTime.Second;
}
else if (startTime.Hour == 16 && startTime.Minute <= 5)
{
//从16点开始小于5分钟以内,以当天18点结束
addHour = 18;
}
else
{
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 9;
var to18senconds = Convert.ToInt32((startTime.Date.AddHours(18) - startTime).TotalSeconds);
addSeconds = 7200 - to18senconds;
}
}
else if (startTime.Hour >= 18)
{
//下一个工作日的18点结束
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 11;
}
}
return startTime.Date.AddDays(addDay).AddHours(addHour).AddSeconds(addSeconds);
}
private DateTime CalculateExpirationTimeFor5WorkHour(DateTime startTime)
{
int addDay = 0, addHour = 0, addSeconds = 0;
//先确定是否为周日
if (startTime.DayOfWeek == DayOfWeek.Sunday)
{
addDay = 1;
addHour = 15;
}
else
{
if (startTime.Hour < 9)
addHour = 15;
else if (startTime.Hour >= 9 && startTime.Hour < 12)
{
addHour = 13;
var to12senconds = Convert.ToInt32((startTime.Date.AddHours(12) - startTime).TotalSeconds);
addSeconds = 18000 - to12senconds;
}
else if (startTime.Hour >= 12 && startTime.Hour < 13)
{
addHour = 18;
}
else if (startTime.Hour >= 13 && startTime.Hour < 18)
{
if (startTime.Hour == 13 && startTime.Minute <= 5)
{
//从16点开始小于5分钟以内,以当天18点结束
addHour = 18;
}
else
{
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 9;
var to18senconds = Convert.ToInt32((startTime.Date.AddHours(18) - startTime).TotalSeconds);
addSeconds = 18000 - to18senconds;
if (addSeconds > 10800)
{
//到第二天9点开始也超过3个小时,就从下午13点开始计算
addHour = 13;
addSeconds -= 10800;
}
}
}
else if (startTime.Hour >= 18)
{
//下一个工作日的18点结束
addDay = CalculateAddDay(startTime.DayOfWeek);
addHour = 15;
}
}
return startTime.Date.AddDays(addDay).AddHours(addHour).AddSeconds(addSeconds);
}
/// <summary>
/// 计算剩余任务时间(秒)
/// </summary>
/// <param name="expirationTime"></param>
/// <returns></returns>
public long CalculateLessTimeForWorkHour(DateTime expirationTime)
{
if (DateTime.Now >= expirationTime)
return 0;
//强制过期时间在工作时间点内
if (expirationTime.Hour < 9)
expirationTime = expirationTime.Date.AddHours(9);
else if (expirationTime.Hour >= 12 && expirationTime.Minute > 0 && expirationTime.Hour < 13) //排除整点结束的到期时间
expirationTime = expirationTime.Date.AddHours(12);
else if (expirationTime.Hour >= 18 && expirationTime.Minute > 0) //排除整点结束的到期时间
expirationTime = expirationTime.Date.AddDays(CalculateAddDay(expirationTime.DayOfWeek)).AddHours(9);
var startTime = DateTime.Now;
long lessTime = 0;
while (true)
{
//把非工作时间段转换成工作时间段
if (startTime.DayOfWeek == DayOfWeek.Sunday)
{
startTime = startTime.Date.AddDays(1).AddHours(9);
}
else
{
if (startTime.Hour < 9)
startTime = startTime.Date.AddHours(9);
else if (startTime.Hour >= 12 && startTime.Hour < 13)
startTime = startTime.Date.AddHours(13);
else if (startTime.Hour >= 18 && startTime.Minute > 0)
startTime = startTime.Date.AddDays(CalculateAddDay(startTime.DayOfWeek)).AddHours(9);
}
//计算上午工作时间段
if (startTime.Hour >= 9 && startTime.Hour < 12)
{
if (expirationTime <= startTime.Date.AddHours(12))
{
lessTime += Convert.ToInt32((expirationTime - startTime).TotalSeconds);
break;
}
else
{
lessTime += 10800;
startTime = startTime.Date.AddHours(13);
}
}
//计算下午工作时间段
if (startTime.Hour >= 13 && startTime.Hour < 18)
{
if (expirationTime <= startTime.Date.AddHours(18))
{
lessTime += Convert.ToInt32((expirationTime - startTime).TotalSeconds);
break;
}
else
{
lessTime += 18000;
startTime = startTime.Date.AddDays(CalculateAddDay(startTime.DayOfWeek)).AddHours(9);
}
}
}
return lessTime;
}
}
}

100
BBWYB.Server.Business/TimeLimitTask/TimeLimitTaskBusiness.cs

@ -3,31 +3,99 @@ using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Dto;
using Microsoft.Extensions.DependencyInjection;
using Yitter.IdGenerator;
namespace BBWYB.Server.Business
{
public class TimeLimitTaskBusiness : BaseBusiness, IDenpendency
{
private VenderBusiness venderBusiness;
private List<Enums.TimeLimitTaskType?> hgzTaskTypeList;
public TimeLimitTaskBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, VenderBusiness venderBusiness) : base(fsql, nLogManager, idGenerator)
private TimeLimitRules timeLimitRules;
private IServiceProvider serviceProvider;
private Lazy<OptimizationBusiness> optimizationBusinessLazy;
private Lazy<VenderBusiness> venderBusinessLazy;
private Lazy<TaskSchedulerManager> taskSchedulerManagerLazy;
private OptimizationBusiness optimizationBusiness => optimizationBusinessLazy.Value;
private VenderBusiness venderBusiness => venderBusinessLazy.Value;
private TaskSchedulerManager taskSchedulerManager => taskSchedulerManagerLazy.Value;
public TimeLimitTaskBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, VenderBusiness venderBusiness, TimeLimitRules timeLimitRules, IServiceProvider serviceProvider) : base(fsql, nLogManager, idGenerator)
{
this.venderBusiness = venderBusiness;
this.serviceProvider = serviceProvider;
this.optimizationBusinessLazy = new Lazy<OptimizationBusiness>(() => serviceProvider.GetRequiredService<OptimizationBusiness>());
this.venderBusinessLazy = new Lazy<VenderBusiness>(() => serviceProvider.GetRequiredService<VenderBusiness>());
this.taskSchedulerManagerLazy = new Lazy<TaskSchedulerManager>(() => serviceProvider.GetRequiredService<TaskSchedulerManager>());
hgzTaskTypeList = new List<Enums.TimeLimitTaskType?>()
{
Enums.TimeLimitTaskType.,
Enums.TimeLimitTaskType.
};
this.timeLimitRules = timeLimitRules;
}
public void CheckTask()
{
fsql.Update<TimeLimitTask>().Set(t => t.IsTimely, false)
.Where(t => t.CompletionTime == null)
.Where(t => t.ExpirationTime < DateTime.Now)
.ExecuteAffrows();
//fsql.Update<TimeLimitTask>().Set(t => t.IsTimely, false)
// .Where(t => t.CompletionTime == null)
// .Where(t => t.ExpirationTime < DateTime.Now)
// .ExecuteAffrows();
var timeoutTaskList = fsql.Select<TimeLimitTask>().Where(t => t.CompletionTime == null && t.ExpirationTime < DateTime.Now).ToList();
if (timeoutTaskList.Count() > 0)
{
var timeoutTaskIdList = timeoutTaskList.Select(t => t.Id).ToList();
fsql.Update<TimeLimitTask>(timeoutTaskIdList).Set(t => t.IsTimely, false).ExecuteAffrows();
}
var optimizationTaskList = timeoutTaskList.Where(t => t.TaskType == Enums.TimeLimitTaskType.).ToList();
if (optimizationTaskList.Count() > 0)
{
//待议价任务超时检查
foreach (var task in optimizationTaskList)
{
Task.Factory.StartNew(() => optimizationBusiness.TimeLimitTaskTimeOutCallBack(task.TaskId), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.OptimizationTaskScheduler);
}
}
}
/// <summary>
/// 修复订单待核算任务
/// </summary>
public void RepairOrderComputationTask()
{
var childSelect = fsql.Select<TimeLimitTask>().As("t").Where(t => t.TaskType == Enums.TimeLimitTaskType.);
var noComputationTaskOrderList = fsql.Select<Order>().Where(o => o.OrderState == Enums.OrderState. &&
!childSelect.Where(t => t.OrderId == o.Id).Any())
.ToList(o => new
{
o.Id,
o.OrderSn,
o.ShopId,
});
var insertComputationTaskList = noComputationTaskOrderList.Select(o => new TimeLimitTask()
{
Id = idGenerator.NewLong(),
CreateTme = DateTime.Now,
OrderId = o.Id,
OrderSn = o.OrderSn,
ShopId = o.ShopId,
TaskType = Enums.TimeLimitTaskType.,
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType., DateTime.Now),
//ExpirationTime = DateTime.Now.AddDays(1),
Remark = "RepairOrderComputationTask"
}).ToList();
if (insertComputationTaskList.Count() > 0)
{
fsql.Transaction(() =>
{
fsql.Insert(insertComputationTaskList).ExecuteAffrows();
});
}
}
public TimeLimitTaskListResponse QueryTimeLimitTask(QueryTimeLimitTaskRequest request)
{
@ -54,6 +122,8 @@ namespace BBWYB.Server.Business
{
var shopId = task.ShopId.ToString();
task.ShopName = shopList.FirstOrDefault(s => s.ShopId == shopId)?.ShopName;
if (task.CompletionTime == null)
task.RemainingTime = timeLimitRules.CalculateLessTimeForWorkHour(task.ExpirationTime.Value);
}
return new TimeLimitTaskListResponse()
{
@ -122,9 +192,9 @@ namespace BBWYB.Server.Business
var purchaseTaskTimeOutCount = purchaseTaskTimOutCountGroups.FirstOrDefault(x => x.ShopId == response.ShopId)?.TaskCount ?? 0;
response.PurchaseTimeOutPercent = purchaseTaskCount == 0 ? 0 : Math.Round(1.0 * purchaseTaskTimeOutCount / purchaseTaskCount * 100, 2);
response.CerEditTimeOutCount = cerTimeOutCountGroups.FirstOrDefault(x => x.ShopId == response.ShopId &&
response.CerEditTimeOutCount = cerTimeOutCountGroups.FirstOrDefault(x => x.ShopId == response.ShopId &&
x.TaskType == Enums.TimeLimitTaskType.)?.TaskCount ?? 0;
response.CerConfigTimeOutCount = cerTimeOutCountGroups.FirstOrDefault(x => x.ShopId == response.ShopId &&
response.CerConfigTimeOutCount = cerTimeOutCountGroups.FirstOrDefault(x => x.ShopId == response.ShopId &&
x.TaskType == Enums.TimeLimitTaskType.)?.TaskCount ?? 0;
list.Add(response);
}
@ -136,5 +206,17 @@ namespace BBWYB.Server.Business
{
fsql.Update<TimeLimitTask>(request.TaskId).Set(t => t.Remark, request.Remark).ExecuteAffrows();
}
public DateTime TestExpireTime(Enums.TimeLimitTaskType timeLimitTaskType, DateTime startTime)
{
return timeLimitRules.CalculateExpirationTime(timeLimitTaskType, startTime);
}
public (long, TimeSpan) TextLessTime(DateTime expireTime)
{
var time = timeLimitRules.CalculateLessTimeForWorkHour(expireTime);
return (time, new TimeSpan(0, 0, (int)time));
}
}
}

45
BBWYB.Server.Business/Users/userBusiness.cs

@ -0,0 +1,45 @@
using BBWYB.Common.Models;
using BBWYB.Server.Model.Db;
namespace BBWYB.Server.Business
{
public class UserBusiness : IDenpendency
{
private FreeSqlMultiDBManager fsqlManager;
public UserBusiness(FreeSqlMultiDBManager fsqlManager)
{
this.fsqlManager = fsqlManager;
}
/// <summary>
/// 获取指定用户的议价组信息
/// </summary>
/// <param name="userId"></param>
/// <param name="throwExWhenUserNotBelongYJ">当用户不属于议价组团队是否抛出错误</param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
public (User user, Userdepartment mainTeam, bool isBargainTeam, Userdepartment? bargainTeam) GetisBargainTeamByUserId(string userId, bool throwExWhenUserNotBelongYJ = false)
{
var user = fsqlManager.MDSfsql.Select<User>(userId).ToOne();
if (user == null)
throw new BusinessException("用户不存在");
if (string.IsNullOrEmpty(user.DepartmentId))
throw new BusinessException("该用户没有归属部门");
var queryDeparmentIdList = new List<string>() { user.DepartmentId };
if (!string.IsNullOrEmpty(user.SonDepartmentIds))
queryDeparmentIdList.AddRange(user.SonDepartmentIds.Split(",", StringSplitOptions.RemoveEmptyEntries));
var departmentList = fsqlManager.MDSfsql.Select<Userdepartment>(queryDeparmentIdList).ToList();
if (departmentList.Count() == 0)
throw new BusinessException("未获取部门");
var mainTeam = departmentList.FirstOrDefault(d => d.Id == user.DepartmentId);
if (mainTeam == null)
throw new BusinessException("主部门不存在");
var bargainTeam = departmentList.FirstOrDefault(d => d.ParentDepartmentId == "1760971468360912896");
if (throwExWhenUserNotBelongYJ && bargainTeam == null)
throw new BusinessException("子部门不属于议价组");
return (user, mainTeam, bargainTeam != null, bargainTeam);
}
}
}

43
BBWYB.Server.Business/Vender/VenderBusiness.cs

@ -1,9 +1,11 @@
using BBWYB.Common.Log;
using BBWYB.Common.Models;
using BBWYB.Server.Model;
using BBWYB.Server.Model.Db;
using BBWYB.Server.Model.Db.Mds;
using BBWYB.Server.Model.Db.MDS;
using BBWYB.Server.Model.Dto;
using Org.BouncyCastle.Ocsp;
using SDKAdapter.OperationPlatform.Client;
using SDKAdapter.OperationPlatform.Models;
using Yitter.IdGenerator;
@ -39,8 +41,13 @@ namespace BBWYB.Server.Business
.ToList<ShopResponse>();
}
public IList<UserDepartmentResponse> GetYiJiaGroup()
{
return fsqlManager.MDSfsql.Select<Userdepartment>().Where(d => d.ParentDepartmentId == "1760971468360912896").ToList<UserDepartmentResponse>();
}
public long SaveShopSetting(ShopSettingRequest shopSettingRequest)
public string SaveShopSetting(ShopSettingRequest shopSettingRequest)
{
//根据shopId查询mds shop的主键Id
var shopId = shopSettingRequest.ShopId.ToString();
@ -48,13 +55,18 @@ namespace BBWYB.Server.Business
if (mdsShop == null)
throw new BusinessException($"mds未找到shopId {shopSettingRequest.ShopId}");
if (shopSettingRequest.PurchaseAccountId == 0)
if (string.IsNullOrEmpty(shopSettingRequest.PurchaseAccountId) || shopSettingRequest.PurchaseAccountId == "0")
{
shopSettingRequest.PurchaseAccountId = idGenerator.NewLong();
var isRepeat = fsqlManager.MDSfsql.Select<Purchaseaccount>().Where(pa => pa.ShopId == mdsShop.Id &&
pa.AppKey == shopSettingRequest.AppKey &&
pa.AppToken == shopSettingRequest.AppToken).Any();
if (isRepeat)
throw new BusinessException($"采购账号重复");
shopSettingRequest.PurchaseAccountId = idGenerator.NewLong().ToString();
var mdspa = new Purchaseaccount()
{
Id = shopSettingRequest.PurchaseAccountId.ToString(),
Id = shopSettingRequest.PurchaseAccountId,
AccountName = shopSettingRequest.AccountName,
AppKey = shopSettingRequest.AppKey,
AppSecret = shopSettingRequest.AppSecret,
@ -70,7 +82,7 @@ namespace BBWYB.Server.Business
}
else
{
fsqlManager.MDSfsql.Update<Purchaseaccount>(shopSettingRequest.PurchaseAccountId.ToString())
fsqlManager.MDSfsql.Update<Purchaseaccount>(shopSettingRequest.PurchaseAccountId)
.Set(pa => pa.AppKey, shopSettingRequest.AppKey)
.Set(pa => pa.AppSecret, shopSettingRequest.AppSecret)
.Set(pa => pa.AppToken, shopSettingRequest.AppToken)
@ -81,6 +93,27 @@ namespace BBWYB.Server.Business
return shopSettingRequest.PurchaseAccountId;
}
public IList<Purchaseaccount> GetPurchaserList(QueryPurchaseAccountRequest request)
{
var purchasePlatofrmId = request.PurchasePlatofrmId != null ? ((int)request.PurchasePlatofrmId).ToString() : string.Empty;
var shopIdStr = request.ShopId.ToString();
var mdsShop = fsqlManager.MDSfsql.Select<Shops>().Where(s => s.ShopId == shopIdStr).ToOne();
var plist = fsqlManager.MDSfsql.Select<Purchaseaccount>()
.Where(pa => pa.ShopId == mdsShop.Id && pa.Deleted == 0)
.WhereIf(!string.IsNullOrEmpty(purchasePlatofrmId), pa => pa.PurchasePlatformId == purchasePlatofrmId)
.WhereIf(!string.IsNullOrEmpty(request.AccountName), pa => pa.AccountName == request.AccountName)
.ToList();
foreach (var pa in plist)
pa.ShopId = shopIdStr;
return plist;
}
public void DeletePurchaseAccount(long purchaseAccountId)
{
var pk = purchaseAccountId.ToString();
fsqlManager.MDSfsql.Update<Purchaseaccount>(pk).Set(pa => pa.Deleted, 1).ExecuteAffrows();
}
public IList<OP_QueryExpressCompanyResponse> GetExpressCompanyList(PlatformRequest request)
{
return opPlatformClientFactory.GetClient((SDKAdapter.AdapterEnums.PlatformType)request.Platform)

57
BBWYB.Server.Model/Db/BBWY/ProductSku.cs

@ -0,0 +1,57 @@
using FreeSql.DataAnnotations;
using System;
namespace BBWYB.Server.Model.Db.BBWY
{
[Table(Name = "productsku", DisableSyncStructure = true)]
public partial class ProductSku
{
/// <summary>
/// SKU
/// </summary>
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
public string Logo { get; set; }
[Column(DbType = "int(1)", MapType = typeof(int))]
public Enums.Platform Platform { get; set; }
/// <summary>
/// 售价
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? Price { get; set; }
/// <summary>
/// SPU
/// </summary>
[Column(StringLength = 50)]
public string ProductId { get; set; }
public long? ShopId { get; set; }
public string Title { get; set; }
/// <summary>
/// 京东Sku状态【1:上架 2:下架 4:删除】
/// </summary>
public int? State { get; set; }
/// <summary>
/// 三级类目Id
/// </summary>
public int? CategoryId { get; set; }
public string CategoryName { get; set; }
}
}

130
BBWYB.Server.Model/Db/BBWY/PurchaseOrderSku.cs

@ -0,0 +1,130 @@
using FreeSql.DataAnnotations;
using Newtonsoft.Json;
using System;
namespace BBWYB.Server.Model.Db.BBWY
{
/// <summary>
/// 采购商品表
/// </summary>
[Table(Name = "purchaseordersku", DisableSyncStructure = true)]
public partial class PurchaseOrderSku
{
[Column(IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 打包耗材费
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? ConsumableAmount { get; set; } = 0.00M;
/// <summary>
/// 创建时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 头程运费
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? FirstFreight { get; set; } = 0.00M;
/// <summary>
/// 入仓费
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? InStorageAmount { get; set; } = 0.00M;
/// <summary>
/// Sku Logo
/// </summary>
public string Logo { get; set; }
/// <summary>
/// 单价
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? Price { get; set; } = 0.00M;
/// <summary>
/// 采购货款
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? ProductAmount { get; set; }
[Column(StringLength = 100)]
public string ProductId { get; set; }
/// <summary>
/// 采购金额(采购货款+采购运费)
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? PurchaseAmount { get; set; }
/// <summary>
/// 采购运费
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? PurchaseFreight { get; set; }
/// <summary>
/// 采购单Id
/// </summary>
[Column(StringLength = 100)]
public string PurchaseOrderId { get; set; }
/// <summary>
/// 采购方案Id
/// </summary>
public long? PurchaseSchemeId { get; set; }
/// <summary>
/// 采购SkuId串
/// </summary>
[Column(StringLength = 500)]
public string PurchaseSkuIds { get; set; }
/// <summary>
/// 质检费
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? QualityInspectionAmount { get; set; } = 0.00M;
/// <summary>
/// 采购数量
/// </summary>
public int? Quantity { get; set; }
/// <summary>
/// 店铺Id
/// </summary>
public long? ShopId { get; set; }
[Column(StringLength = 100)]
public string SkuId { get; set; }
/// <summary>
/// Sku标题
/// </summary>
public string SkuTitle { get; set; }
[Column(MapType = typeof(int?))]
public Enums.StockType? StockType { get; set; }
/// <summary>
/// 齐库任务Id
/// </summary>
public long? QiKuTaskId { get; set; }
}
}

99
BBWYB.Server.Model/Db/BBWY/SkuRecentCost.cs

@ -0,0 +1,99 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db.BBWY
{
[Table(Name = "skurecentcost", DisableSyncStructure = true)]
public partial class SkuRecentCost
{
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string SkuId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(StringLength = 50)]
public string ProductId { get; set; }
/// <summary>
/// 最近一笔订单来源
/// </summary>
[Column(StringLength = 50)]
public string RecentOrderId { get; set; }
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
/// <summary>
/// 耗材费(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleConsumableAmount { get; set; } = 0.00M;
/// <summary>
/// 发货运费(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleDeliveryFreight { get; set; } = 0.00M;
/// <summary>
/// 头程运费(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleFirstFreight { get; set; }
/// <summary>
/// 采购运费(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleFreight { get; set; } = 0.00M;
/// <summary>
/// 入仓操作费(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleInStorageAmount { get; set; } = 0.00M;
/// <summary>
/// 操作费(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleOperationAmount { get; set; } = 0.00M;
/// <summary>
/// 出仓操作费(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleOutStorageAmount { get; set; } = 0.00M;
///// <summary>
///// 退货入仓操作费(单件)
///// </summary>
//[Column(DbType = "decimal(20,2)")]
//public decimal? SingleRefundInStorageAmount { get; set; } = 0.00M;
/// <summary>
/// SKU成本(单件)
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SingleSkuAmount { get; set; }
///// <summary>
///// 仓储费(单件)
///// </summary>
//[Column(DbType = "decimal(20,2)")]
//public decimal? SingleStorageAmount { get; set; } = 0.00M;
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 包装人工单价
/// </summary>
[Column(DbType = "decimal(20,2)")]
public decimal? SinglePackagingLaborAmount { get; set; } = 0.00M;
}
}

2
BBWYB.Server.Model/Db/HY/HY重新生成.bat

@ -0,0 +1,2 @@
FreeSql.Generator -Razor 1 -NameOptions 1,0,0,0 -NameSpace BBWYB.Server.Model.Db -DB "MySql,data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=jdhy;charset=utf8;sslmode=none;" -FileName "{name}.cs"

47
BBWYB.Server.Model/Db/HY/Hycats.cs

@ -0,0 +1,47 @@
using FreeSql.DatabaseModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db.HY
{
[Table(Name = "hycats", DisableSyncStructure = true)]
public partial class HyCats
{
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
/// <summary>
/// 是否最子级
/// </summary>
[Column(DbType = "tinyint")]
public sbyte IsLeaf { get; set; }
/// <summary>
/// 级别
/// </summary>
[Column(DbType = "int")]
public int Level { get; set; }
/// <summary>
/// 名称
/// </summary>
[Column(IsNullable = false)]
public string Name { get; set; }
/// <summary>
/// 父级ID
/// </summary>
[Column(StringLength = 50)]
public string ParentId { get; set; }
}
}

67
BBWYB.Server.Model/Db/HY/__razor.cshtml.txt

@ -0,0 +1,67 @@
using FreeSql.DatabaseModel;@{
var gen = Model as RazorModel;
Func<string, string> GetAttributeString = attr => {
if (string.IsNullOrEmpty(attr)) return "";
return string.Concat(", ", attr.Trim('[', ']'));
};
Func<string, string> GetDefaultValue = defval => {
if (string.IsNullOrEmpty(defval)) return "";
return " = " + defval + ";";
};
}@{
switch (gen.fsql.Ado.DataType) {
case FreeSql.DataType.PostgreSQL:
@:using System;
@:using System.Collections;
@:using System.Collections.Generic;
@:using System.Linq;
@:using System.Reflection;
@:using System.Threading.Tasks;
@:using Newtonsoft.Json;
@:using FreeSql.DataAnnotations;
@:using System.Net;
@:using Newtonsoft.Json.Linq;
@:using System.Net.NetworkInformation;
@:using NpgsqlTypes;
@:using Npgsql.LegacyPostgis;
break;
case FreeSql.DataType.SqlServer:
case FreeSql.DataType.MySql:
default:
@:using System;
@:using System.Collections;
@:using System.Collections.Generic;
@:using System.Linq;
@:using System.Reflection;
@:using System.Threading.Tasks;
@:using Newtonsoft.Json;
@:using FreeSql.DataAnnotations;
break;
}
}
namespace @gen.NameSpace {
@if (string.IsNullOrEmpty(gen.table.Comment) == false) {
@:/// <summary>
@:/// @gen.table.Comment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")
@:/// </summary>
}
[JsonObject(MemberSerialization.OptIn)@GetAttributeString(gen.GetTableAttribute())]
public partial class @gen.GetCsName(gen.FullTableName) {
@foreach (var col in gen.columns) {
if (string.IsNullOrEmpty(col.Comment) == false) {
@:/// <summary>
@:/// @col.Comment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")
@:/// </summary>
}
@:@("[JsonProperty" + GetAttributeString(gen.GetColumnAttribute(col, true)) + "]")
@:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(gen.GetColumnDefaultValue(col, false))
@:
}
}
@gen.GetMySqlEnumSetDefine()
}

2
BBWYB.Server.Model/Db/HY/__重新生成.bat

@ -0,0 +1,2 @@

FreeSql.Generator -Razor "__razor.cshtml.txt" -NameOptions 1,0,0,0 -NameSpace BBWYB.Server.Model.Db -DB "MySql,data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=jdhy;charset=utf8;sslmode=none;" -FileName "{name}.cs"

132
BBWYB.Server.Model/Db/MDS/User.cs

@ -0,0 +1,132 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
[Table(Name = "user", DisableSyncStructure = true)]
public partial class User
{
/// <summary>
/// 主键
/// </summary>
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
/// <summary>
/// 业务ID列表
/// </summary>
[Column(StringLength = -2)]
public string BusinessIds { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 创建人Id
/// </summary>
[Column(StringLength = 50)]
public string CreatorId { get; set; }
/// <summary>
/// 否已删除
/// </summary>
[Column(DbType = "tinyint(4)")]
public sbyte Deleted { get; set; }
/// <summary>
/// 主部门ID
/// </summary>
[Column(StringLength = 50)]
public string DepartmentId { get; set; }
/// <summary>
/// 即将过期积分
/// </summary>
public int? FailureIntegral { get; set; }
/// <summary>
/// 当日冻结积分
/// </summary>
public int? FreezeIntegral { get; set; }
/// <summary>
/// 是否冻结
/// </summary>
[Column(DbType = "tinyint(4)")]
public sbyte? IsFreeze { get; set; }
/// <summary>
/// 最后积分检测日期
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastIntegralDate { get; set; }
/// <summary>
/// 登录IP
/// </summary>
public string LoginIp { get; set; }
/// <summary>
/// 最大任务数量
/// </summary>
public int? MaxPriceTaskCount { get; set; }
/// <summary>
/// 角色ID
/// </summary>
[Column(StringLength = 50)]
public string RoleId { get; set; }
/// <summary>
/// 子部门列表
/// </summary>
[Column(StringLength = -1)]
public string SonDepartmentIds { get; set; }
/// <summary>
/// 任务重复检测更新
/// </summary>
[Column(DbType = "datetime")]
public DateTime? UpdateRepeatDate { get; set; }
/// <summary>
/// 用户经验值
/// </summary>
public int? UserExp { get; set; }
/// <summary>
/// 用户积分
/// </summary>
public int? UserIntegral { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 花名
/// </summary>
public string UserNick { get; set; }
/// <summary>
/// 用户密码
/// </summary>
public string UserPwd { get; set; }
}
}

56
BBWYB.Server.Model/Db/MDS/Userdepartment.cs

@ -0,0 +1,56 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 团队
/// </summary>
[Table(Name = "userdepartment", DisableSyncStructure = true)]
public partial class Userdepartment
{
/// <summary>
/// 主键
/// </summary>
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
/// <summary>
/// 管理ID集合
/// </summary>
[Column(StringLength = -1)]
public string AdminUserIds { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 创建人Id
/// </summary>
[Column(StringLength = 50)]
public string CreatorId { get; set; }
/// <summary>
/// 否已删除
/// </summary>
[Column(DbType = "tinyint(4)")]
public sbyte Deleted { get; set; }
/// <summary>
/// 部门名称
/// </summary>
public string DepartmentName { get; set; }
/// <summary>
/// 上级部门
/// </summary>
[Column(StringLength = 50)]
public string ParentDepartmentId { get; set; }
}
}

3
BBWYB.Server.Model/Db/Order/OrderPurchaseInfo.cs

@ -15,6 +15,9 @@ namespace BBWYB.Server.Model.Db
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// ²É¹ºÕ˺ÅId
/// </summary>

17
BBWYB.Server.Model/Db/Order/OrderPurchaseSkuInfo.cs

@ -62,6 +62,23 @@ namespace BBWYB.Server.Model.Db
/// </summary>
[Column(StringLength = 100)]
public string WaybillNo { get; set; }
/// <summary>
/// 采购数量
/// </summary>
public int PurchasedItemCount { get; set; } = 1;
/// <summary>
/// 采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal PurchasedAmount { get; set; } = 0.00M;
/// <summary>
/// 采购单价
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal PurchasedPrice { get; set; } = 0.00M;
}
}

18
BBWYB.Server.Model/Db/Order/OrderSku.cs

@ -102,6 +102,24 @@ namespace BBWYB.Server.Model.Db
/// </summary>
[Column(DbType = "bit", IsNullable = true)]
public bool? IsCheck { get; set; }
/// <summary>
/// 是否需要优化 是=1 否=0
/// </summary>
[Column(DbType = "int(1)", IsNullable = true)]
public int? IsNeedOptimization { get; set; } = 0;
/// <summary>
/// 是否优化完成 是=1 否=0
/// </summary>
[Column(DbType = "int(1)", IsNullable = true)]
public int? IsOptimizationCompleted { get; set; } = 0;
/// <summary>
/// 触发优化原因
/// </summary>
[Column(DbType = "int(1)", MapType = typeof(int?), IsNullable = true)]
public Enums.TriggerOptimizationReason? TriggerOptimizationReason { get; set; }
}
}

65
BBWYB.Server.Model/Db/Product/Product.cs

@ -0,0 +1,65 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 商品表(SPU)
/// </summary>
[Table(Name = "product", DisableSyncStructure = true)]
public partial class Product
{
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
public string Logo { get; set; }
/// <summary>
/// 商品名称
/// </summary>
[Column(StringLength = 200)]
public string ProductName { get; set; }
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
/// <summary>
/// 状态(0下架 1上架)
/// </summary>
[Column(DbType = "int")]
public int? State { get; set; }
/// <summary>
/// 同步时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? SyncTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 最近上架时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? UpperTime { get; set; }
/// <summary>
/// 分类Id
/// </summary>
[Column(DbType = "bigint")]
public long? CategoryId { get; set; }
/// <summary>
/// 分类名称
/// </summary>
[Column(StringLength = 50)]
public string CategoryName { get; set; }
}
}

71
BBWYB.Server.Model/Db/Product/ProductSku.cs

@ -0,0 +1,71 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 商品Sku表
/// </summary>
[ Table(Name = "productsku", DisableSyncStructure = true)]
public partial class ProductSku {
/// <summary>
/// SkuId
/// </summary>
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
public string Logo { get; set; }
[Column(DbType = "decimal(18,2)")]
public decimal? Price { get; set; } = 0.00M;
[Column(StringLength = 50)]
public string ProductId { get; set; }
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
[Column(StringLength = 200)]
public string SkuName { get; set; }
/// <summary>
/// 0下架 1上架
/// </summary>
[Column(DbType = "int")]
public int? State { get; set; }
/// <summary>
/// 同步时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? SyncTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 最近上架时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? UpperTime { get; set; }
/// <summary>
/// 分类Id
/// </summary>
[Column(DbType = "bigint")]
public long? CategoryId { get; set; }
/// <summary>
/// 分类名称
/// </summary>
[Column(StringLength = 50)]
public string CategoryName { get; set; }
}
}

48
BBWYB.Server.Model/Db/Product/Skutotalsaleinfo.cs

@ -0,0 +1,48 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// Sku总销量表
/// </summary>
[Table(Name = "skutotalsaleinfo", DisableSyncStructure = true)]
public partial class SkuTotalSaleInfo
{
/// <summary>
/// Sku
/// </summary>
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string SkuId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 是否有效
/// </summary>
public bool? IsEnabled { get; set; } = false;
/// <summary>
/// 销量,销售件数
/// </summary>
[Column(DbType = "bigint")]
public long? ItemCount { get; set; } = 0;
/// <summary>
/// Spu
/// </summary>
[Column(StringLength = 50)]
public string ProductId { get; set; }
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
}
}

75
BBWYB.Server.Model/Db/Product/SpuTotalSaleInfo.cs

@ -0,0 +1,75 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// Spu总销量表
/// </summary>
[Table(Name = "sputotalsaleinfo", DisableSyncStructure = true)]
public partial class SpuTotalSaleInfo
{
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string ProductId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 完成首次优化时的销量
/// </summary>
[Column(DbType = "bigint")]
public long? FirstOptimizationCompletedItemCount { get; set; } = 0;
/// <summary>
/// 完成首次采购时的销量
/// </summary>
[Column(DbType = "bigint")]
public long? FirstPurchaseCompletedItemCount { get; set; } = 0;
/// <summary>
/// 是否有效
/// </summary>
public bool? IsEnabled { get; set; } = false;
/// <summary>
/// 是否完成首次优化
/// </summary>
public bool? IsFirstOptimizationCompleted { get; set; } = false;
/// <summary>
/// 是否完成首次采购
/// </summary>
public bool? IsFirstPurchaseCompleted { get; set; } = false;
/// <summary>
/// 销量,销售件数
/// </summary>
[Column(DbType = "bigint")]
public long? ItemCount { get; set; } = 0;
/// <summary>
/// 上次优化时的销量
/// </summary>
[Column(DbType = "bigint")]
public long? LastOptimizationItemCount { get; set; } = 0;
/// <summary>
/// 上次优化时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastOptimizationTime { get; set; }
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
}
}

70
BBWYB.Server.Model/Db/PurchaseScheme/PurchaseScheme.cs

@ -29,7 +29,7 @@ namespace BBWYB.Server.Model
public decimal DefaultCost { get; set; } = 0.0M;
/// <summary>
/// 上次采购成本
/// 采购方案最近采购成本(配件单价之和)
/// </summary>
public decimal LastPurchasePriceCost { get; set; } = 0.0M;
@ -50,6 +50,7 @@ namespace BBWYB.Server.Model
/// <summary>
/// 最后采购时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastPurchaseTime { get; set; }
/// <summary>
@ -78,6 +79,73 @@ namespace BBWYB.Server.Model
[Column(IsIgnore = true)]
public List<PurchaseSchemeProduct> PurchaseSchemeProductList { get; set; }
/// <summary>
/// 议价成本,只有当任意配件包含议价成本时才具备此值
/// </summary>
public decimal? BargainingCost { get; set; }
/// <summary>
/// 采购次数
/// </summary>
public int? PurchasedCount { get; set; } = 0;
/// <summary>
/// 采购金额
/// </summary>
public decimal? PurchasedAmount { get; set; } = 0M;
/// <summary>
/// 首选采购方案 (是=1 否=0)
/// </summary>
public int? IsFirst { get; set; } = 0;
/// <summary>
/// 最近议价日期
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastBargainingTime { get; set; }
/// <summary>
/// 采购件数
/// </summary>
public int? PurchasedItemCount { get; set; } = 0;
/// <summary>
/// 归属议价组Id
/// </summary>
[Column(StringLength = 50)]
public string BelongBargainTeamId { get; set; }
/// <summary>
/// 归属议价组名称
/// </summary>
[Column(StringLength = 50)]
public string BelongBargainTeamName { get; set; }
/// <summary>
/// 更新人Id
/// </summary>
[Column(StringLength = 50)]
public string UpdateUserId { get; set; }
/// <summary>
/// 更新人团队Id
/// </summary>
[Column(StringLength = 50)]
public string UpdateTeamId { get; set; }
/// <summary>
/// 是否为议价组更新
/// </summary>
[Column(DbType = "bit")]
public bool? IsBargainTeamUpdate { get; set; } = false;
/// <summary>
/// 是否包邮
/// </summary>
[Column(DbType = "bit")]
public bool? IsFreeFreight { get; set; } = false;
}
}

69
BBWYB.Server.Model/Db/PurchaseScheme/PurchaseSchemeGroup.cs

@ -7,39 +7,44 @@ namespace BBWYB.Server.Model.Db
/// 采购方案分组表
/// </summary>
[Table(Name = "purchaseschemegroup", DisableSyncStructure = true)]
public partial class PurchaseSchemeGroup
public partial class PurchaseSchemeGroup
{
/// <summary>
/// 分组Id
/// </summary>
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 组名
/// </summary>
[Column(StringLength = 100)]
public string GroupName { get; set; }
/// <summary>
/// 店铺spu,店铺商品Id
/// </summary>
[Column(StringLength = 50)]
public string ProductId { get; set; }
/// <summary>
/// 店铺Id
/// </summary>
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
}
/// <summary>
/// 分组Id
/// </summary>
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 组名
/// </summary>
[Column(StringLength = 100)]
public string GroupName { get; set; }
/// <summary>
/// 店铺spu,店铺商品Id
/// </summary>
[Column(StringLength = 50)]
public string ProductId { get; set; }
/// <summary>
/// 店铺Id
/// </summary>
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
/// <summary>
/// 归属议价组
/// </summary>
[Column(StringLength = 50)]
public string BelongBargainTeamId { get; set; }
}
}

42
BBWYB.Server.Model/Db/PurchaseScheme/PurchaseSchemeProductSkuStatistic.cs

@ -0,0 +1,42 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
[Table(Name = "purchaseschemeproductskustatistic", DisableSyncStructure = true)]
public partial class PurchaseSchemeProductSkuStatistic
{
[Column(StringLength = 50, IsPrimary = true, IsNullable = false)]
public string PurchaseSkuId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 最近采购单价
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? LastPurchasedPrice { get; set; } = 0.00M;
/// <summary>
/// 最近采购时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastPurchasedTime { get; set; }
/// <summary>
/// 采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? PurchasedAmount { get; set; }
/// <summary>
/// 采购件数
/// </summary>
[Column(DbType = "int")]
public int? PurchasedItemCount { get; set; } = 0;
}
}

49
BBWYB.Server.Model/Db/PurchaseScheme/Purchaser.cs

@ -1,49 +0,0 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 采购商表
/// </summary>
[Table(Name = "purchaser", DisableSyncStructure = true)]
public partial class Purchaser
{
/// <summary>
/// 采购商Id (1688 SellerUserId)
/// </summary>
[Column(StringLength = 20, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
/// <summary>
/// 采购商Id2 (1688 SellerLoginId)
/// </summary>
[Column(StringLength = 50)]
public string Id2 { get; set; }
/// <summary>
/// 采购商名称
/// </summary>
[Column(StringLength = 50)]
public string Name { get; set; }
/// <summary>
/// 发货地
/// </summary>
[Column(StringLength = 50)]
public string Location { get; set; }
/// <summary>
/// 采购平台
/// </summary>
[Column(MapType = typeof(int?))]
public Enums.Platform? Platform { get; set; }
[Column(StringLength = 50, IsNullable = true)]
public string MemberId { get; set; }
}
}

13
BBWYB.Server.Model/Db/PurchaseScheme/Purchaseschemeproductsku.cs

@ -55,7 +55,18 @@ namespace BBWYB.Server.Model.Db
/// <summary>
/// 实际单价
/// </summary>
public decimal? ActualPrice { get; set; } = 0.00M;
public decimal? ActualPrice { get; set; }
/// <summary>
/// 最近议价日期
/// </summary>
[Column(DbType = "datetime", IsNullable = true)]
public DateTime? LastBargainingTime { get; set; }
/// <summary>
/// 配件的最近采购价(配件单价)
/// </summary>
public decimal? LastPurchasePriceCost { get; set; }
}

15
BBWYB.Server.Model/Db/PurchaseScheme/history/HistoryPurchaseScheme.cs

@ -78,6 +78,21 @@ namespace BBWYB.Server.Model.Db
[Column(DbType = "int")]
public int? Version { get; set; } = 1;
/// <summary>
/// 议价成本,只有当任意配件包含议价成本时才具备此值
/// </summary>
public decimal? BargainingCost { get; set; }
/// <summary>
/// 采购次数
/// </summary>
public int? PurchasedCount { get; set; } = 0;
/// <summary>
/// 采购金额
/// </summary>
public decimal? PurchasedAmount { get; set; } = 0M;
}
}

39
BBWYB.Server.Model/Db/PurchaseScheme/history/SkuHistoryPurchaserRelation.cs

@ -0,0 +1,39 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// Sku历史采购商关系表
/// </summary>
[Table(Name = "skuhistorypurchaserrelation", DisableSyncStructure = true)]
public partial class SkuHistoryPurchaserRelation
{
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 采购商Id
/// </summary>
[Column(StringLength = 50)]
public string PurchaserId { get; set; }
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
/// <summary>
/// 店铺Sku
/// </summary>
[Column(StringLength = 50)]
public string SkuId { get; set; }
}
}

136
BBWYB.Server.Model/Db/Purchaser/Purchaser.cs

@ -0,0 +1,136 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// 采购商表
/// </summary>
[Table(Name = "purchaser", DisableSyncStructure = true)]
public partial class Purchaser
{
/// <summary>
/// 采购商Id (1688 SellerUserId)
/// </summary>
[Column(StringLength = 20, IsPrimary = true, IsNullable = false)]
public string Id { get; set; }
/// <summary>
/// 采购商Id2 (1688 SellerLoginId)
/// </summary>
[Column(StringLength = 50)]
public string Id2 { get; set; }
/// <summary>
/// 发货地(产地)
/// </summary>
[Column(StringLength = 50)]
public string Location { get; set; }
/// <summary>
/// 经营模式 0贸易 1厂家
/// </summary>
[Column(DbType = "int", MapType = typeof(int))]
public Enums.ManagmentMode? ManagmentMode { get; set; }
/// <summary>
/// 经营模式(文本)
/// </summary>
public string ManagmentModeText { get; set; }
[Column(StringLength = 50)]
public string MemberId { get; set; }
/// <summary>
/// 采购商名称
/// </summary>
[Column(StringLength = 50)]
public string Name { get; set; }
/// <summary>
/// 采购平台
/// </summary>
[Column(MapType = typeof(int?))]
public Enums.Platform? Platform { get; set; }
/// <summary>
/// 商家标签 (超级工厂/实力工厂/实力供应商),可空
/// </summary>
[Column(StringLength = 20)]
public string Tag { get; set; }
/// <summary>
/// 绑定SPU数
/// </summary>
[Column(DbType = "bigint")]
public long? BindingSpuCount { get; set; } = 0;
/// <summary>
/// 采购SPU数
/// </summary>
[Column(DbType = "bigint")]
public long? PurchasedSpuCount { get; set; } = 0;
/// <summary>
/// 绑定SKU数
/// </summary>
[Column(DbType = "bigint")]
public long? BindingSkuCount { get; set; } = 0;
/// <summary>
/// 采购SKU数
/// </summary>
[Column(DbType = "bigint")]
public long? PurchasedSkuCount { get; set; } = 0;
/// <summary>
/// 采购次数/采购订单数
/// </summary>
[Column(DbType = "bigint")]
public long? PurchasedCount { get; set; } = 0;
/// <summary>
/// 采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? PurchasedAmount { get; set; } = 0.00M;
/// <summary>
/// 上次采购时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastPurchasedTime { get; set; }
/// <summary>
/// 最近90天采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? Recent90dPurchasedAmount { get; set; } = 0.00M;
/// <summary>
/// 最近90天采购次数
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? Recent90dPurchasedCount { get; set; } = 0.00M;
/// <summary>
/// 归属议价组Id
/// </summary>
[Column(StringLength = 50)]
public string BelongBargainTeamId { get; set; }
/// <summary>
/// 归属议价组名称
/// </summary>
[Column(StringLength = 50)]
public string BelongBargainTeamName { get; set; }
/// <summary>
/// 临时=0, 永久=1
/// </summary>
[Column(MapType = typeof(int?))]
public Enums.PurchaserBelongType? BelongType { get; set; }
}
}

30
BBWYB.Server.Model/Db/Purchaser/PurchaserExtendedInfo.cs

@ -0,0 +1,30 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
[Table(Name = "purchaserextendedinfo", DisableSyncStructure = true)]
public partial class PurchaserExtendedInfo
{
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(StringLength = 50)]
public string Name { get; set; }
/// <summary>
/// 类型 主营类目=0 标签=1
/// </summary>
[Column(MapType = typeof(int?))]
public Enums.PurchaserBasicInfoType? Type { get; set; }
[Column(StringLength = 50)]
public string ExtendInfo { get; set; }
}
}

27
BBWYB.Server.Model/Db/Purchaser/Purchaser_ExtendedInfo_Relation.cs

@ -0,0 +1,27 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
[Table(Name = "purchaser_extendedInfo_relation", DisableSyncStructure = true)]
public partial class Purchaser_ExtendedInfo_Relation
{
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
[Column(DbType = "bigint")]
public long? ExtendedInfoId { get; set; }
/// <summary>
/// 关系类型 主营类目=0 标签=1
/// </summary>
[Column(DbType = "int",MapType = typeof(int?))]
public Enums.PurchaserBasicInfoType? ExtendedType { get; set; }
[Column(StringLength = 50)]
public string PurchaserId { get; set; }
}
}

57
BBWYB.Server.Model/Db/SpuOptimization/Skuoptimizationhistory.cs

@ -0,0 +1,57 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// Sku历史优化表
/// </summary>
[Table(Name = "skuoptimizationhistory", DisableSyncStructure = true)]
public partial class SkuOptimizationHistory
{
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 优化时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 优化率
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? OptimizationRatio { get; set; }
[Column(StringLength = 50)]
public string ProductId { get; set; }
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
[Column(StringLength = 50)]
public string SkuId { get; set; }
/// <summary>
/// 上次采购单价
/// </summary>
[Column(DbType = "decimal(18,2)", IsNullable = true)]
public decimal? LastPurchasePrice { get; set; } = 0.0M;
/// <summary>
/// 本次采购单价
/// </summary>
[Column(DbType = "decimal(18,2)", IsNullable = true)]
public decimal? CurrentPurchasePrice { get; set; } = 0.0M;
/// <summary>
/// 触发优化原因
/// </summary>
[Column(DbType = "int(1)", MapType = typeof(int?), IsNullable = true)]
public Enums.TriggerOptimizationReason? TriggerOptimizationReason { get; set; }
}
}

45
BBWYB.Server.Model/Db/SpuOptimization/Skuoptimizationtask.cs

@ -0,0 +1,45 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// Sku优化任务表
/// </summary>
[Table(Name = "skuoptimizationtask", DisableSyncStructure = true)]
public partial class SkuOptimizationTask
{
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(StringLength = 50)]
public string JDSkuId { get; set; }
/// <summary>
/// 预估件数
/// </summary>
[Column(DbType = "int")]
public int? PreItemCount { get; set; }
/// <summary>
/// 预估采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? PrePurchaseAmount { get; set; }
[Column(StringLength = 50)]
public string SkuId { get; set; }
/// <summary>
/// Spu优化任务Id
/// </summary>
[Column(DbType = "bigint")]
public long SpuOptimizationTaskId { get; set; }
}
}

47
BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationbargainteamtask.cs

@ -0,0 +1,47 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// SPU优化议价组任务表
/// </summary>
[Table(Name = "spuoptimizationbargainteamtask", DisableSyncStructure = true)]
public partial class SpuOptimizationBargainTeamTask
{
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 团队Id (议价组Id)
/// </summary>
[Column(StringLength = 50)]
public string BelongTeamId { get; set; }
/// <summary>
/// 议价组名称
/// </summary>
[Column(StringLength = 50)]
public string BelongTeamName { get; set; }
/// <summary>
/// 完成时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CompletionTime { get; set; }
/// <summary>
/// 是否优化完成
/// </summary>
public bool? IsOptimizationCompleted { get; set; }
/// <summary>
/// Spu优化任务Id
/// </summary>
[Column(DbType = "bigint")]
public long SpuOptimizationTaskId { get; set; }
}
}

73
BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationcompetitivetendertask.cs

@ -0,0 +1,73 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// SPU优化竞标任务表
/// </summary>
[Table(Name = "spuoptimizationcompetitivetendertask", DisableSyncStructure = true)]
public partial class SpuOptimizationCompetitiveTenderTask
{
[Column(IsPrimary = true, IsNullable = false)]
public long Id { get; set; }
/// <summary>
/// 议价组Id
/// </summary>
[Column(StringLength = 50)]
public string BargainTeamId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 是否更新报价
/// </summary>
public bool? IsUpdateQuotedPrice { get; set; } = false;
/// <summary>
/// 采购方案分组Id
/// </summary>
[Column(DbType = "bigint")]
public long? SchemeGroupId { get; set; }
/// <summary>
/// 采购方案Id
/// </summary>
[Column(DbType = "bigint")]
public long SchemeId { get; set; }
[Column(StringLength = 50)]
public string SkuId { get; set; }
/// <summary>
/// Spu优化议价组任务Id
/// </summary>
[Column(DbType = "bigint")]
public long? SpuOptimizationBargainTeamTaskId { get; set; }
/// <summary>
/// Spu优化任务Id
/// </summary>
[Column(DbType = "bigint")]
public long SpuOptimizationTaskId { get; set; }
/// <summary>
/// 是否中标
/// </summary>
[Column(DbType = "bit")]
public bool IsWin { get; set; } = false;
/// <summary>
/// 运费
/// </summary>
public decimal? Freight { get; set; } = 0.00M;
}
}

29
BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationproductskuupdatequotedpricerecord.cs

@ -0,0 +1,29 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
[Table(Name = "spuoptimizationproductskuupdatequotedpricerecord", DisableSyncStructure = true)]
public partial class SpuOptimizationProductSkuUpdateQuotedPriceRecord
{
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
[Column(StringLength = 50)]
public string BargainTeamId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(StringLength = 50)]
public string PurchaseSkuId { get; set; }
[Column(DbType = "bigint")]
public long? SpuOptimizationTaskId { get; set; }
[Column(StringLength = 50)]
public string UserId { get; set; }
}
}

60
BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationpurchasercompetitvetendertask.cs

@ -0,0 +1,60 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db.SpuOptimization
{
[Table(Name = "spuoptimizationpurchasercompetitivetendertask", DisableSyncStructure = true)]
public partial class SpuOptimizationPurchaserCompetitiveTenderTask
{
[Column(IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 议价组Id
/// </summary>
[Column(StringLength = 50)]
public string BargainTeamId { get; set; }
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
[Column(DbType = "datetime")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 是否更新报价
/// </summary>
public bool? IsUpdateQuotedPrice { get; set; } = false;
/// <summary>
/// 采购商Id
/// </summary>
[Column(StringLength = 50)]
public string PurchaserId { get; set; }
/// <summary>
/// 采购方案分组Id
/// </summary>
[Column(DbType = "bigint")]
public long? SchemeGroupId { get; set; }
/// <summary>
/// 采购方案Id
/// </summary>
[Column(DbType = "bigint")]
public long? SchemeId { get; set; }
[Column(StringLength = 50)]
public string SkuId { get; set; }
/// <summary>
/// Spu优化任务Id
/// </summary>
[Column(DbType = "bigint")]
public long? SpuOptimizationTaskId { get; set; }
}
}

92
BBWYB.Server.Model/Db/SpuOptimization/Spuoptimizationtask.cs

@ -0,0 +1,92 @@
using FreeSql.DataAnnotations;
namespace BBWYB.Server.Model.Db
{
/// <summary>
/// SPU优化任务表
/// </summary>
[Table(Name = "spuoptimizationtask", DisableSyncStructure = true)]
public partial class SpuOptimizationTask
{
/// <summary>
/// 待优化任务Id
/// </summary>
[Column(DbType = "bigint", IsPrimary = true)]
public long Id { get; set; }
/// <summary>
/// 需求方店铺Id
/// </summary>
[Column(DbType = "bigint")]
public long? BelongShopId { get; set; }
/// <summary>
/// 需求方店铺名称
/// </summary>
[Column(StringLength = 50)]
public string BelongShopName { get; set; }
/// <summary>
/// 完成优化时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CompletionTime { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 是否优化完成
/// </summary>
public bool? IsOptimizationCompleted { get; set; }
[Column(StringLength = 50)]
public string ProductId { get; set; }
[Column(StringLength = 255)]
public string ProductTitle { get; set; }
/// <summary>
/// 上次优化时间
/// </summary>
[Column(DbType = "datetime")]
public DateTime? LastOptimizationTime { get; set; }
/// <summary>
/// 预估件数
/// </summary>
[Column(DbType = "int")]
public int? PreItemCount { get; set; }
/// <summary>
/// 预估采购金额
/// </summary>
[Column(DbType = "decimal(18,2)")]
public decimal? PrePurchaseAmount { get; set; }
/// <summary>
/// 预估Sku数
/// </summary>
[Column(DbType = "int")]
public int? PreSkuCount { get; set; }
/// <summary>
/// 店铺Id
/// </summary>
[Column(DbType = "bigint")]
public long? ShopId { get; set; }
/// <summary>
/// 触发优化原因 首次采购 = 0, 首次优化 = 1, 再次优化 = 2;触发优化原因 首次采购 = 0, 首次优化 = 1, 再次优化 = 2
/// </summary>
[Column(DbType = "int", MapType = typeof(int?))]
public Enums.TriggerOptimizationReason? TriggerOptimizationReason { get; set; }
}
}

4
BBWYB.Server.Model/Db/TimeLimitTask/TimeLimitTask.cs

@ -79,6 +79,10 @@ namespace BBWYB.Server.Model.Db
[Column(StringLength = 500)]
public string Remark { get; set; }
/// <summary>
/// 任务Id(待优化任务有效)
/// </summary>
public long TaskId { get; set; }
}
}

30
BBWYB.Server.Model/Dto/Request/LiangKu/BatchLKInventoryAlertRequest.cs

@ -0,0 +1,30 @@
namespace BBWYB.Server.Model.Dto
{
public class BatchLKInventoryAlertRequest
{
/// <summary>
/// 需求方店铺
/// </summary>
public long ShopId { get; set; }
public IList<LKInventoryAlertRequest> Items { get; set; }
}
public class LKInventoryAlertRequest
{
/// <summary>
/// 京东SKU
/// </summary>
public string Sku { get; set; }
/// <summary>
/// 预估需求量
/// </summary>
public int PreItemCount { get; set; }
/// <summary>
/// 距离安全预警天数
/// </summary>
public int SafeWarningRemainingDay { get; set; }
}
}

45
BBWYB.Server.Model/Dto/Request/Optimization/BatchUpdateCompetitiveTenderQuotationRequest.cs

@ -0,0 +1,45 @@
namespace BBWYB.Server.Model.Dto
{
public class BatchUpdateCompetitiveTenderQuotationRequest
{
/// <summary>
/// 优化任务Id
/// </summary>
public long SpuOptimizationTaskId { get; set; }
/// <summary>
/// 采购方案分组Id
/// </summary>
public long SchemeGroupId { get; set; }
/// <summary>
/// 配件列表
/// </summary>
public IList<BatchUpdateCompetitiveTenderQuotationItemRequest> ItemList { get; set; }
/// <summary>
/// 运费
/// </summary>
public decimal Freight { get; set; }
}
public class BatchUpdateCompetitiveTenderQuotationItemRequest
{
//public string SkuId { get; set; }
/// <summary>
/// 采购SkuId
/// </summary>
public string PurchaseSkuId { get; set; }
/// <summary>
/// 实际单价
/// </summary>
public decimal? ActualPrice { get; set; }
/// <summary>
/// 是否包邮
/// </summary>
public bool IsFreeFreight { get; set; }
}
}

44
BBWYB.Server.Model/Dto/Request/Optimization/QueryNoCompletionOptimizationTaskRequest.cs

@ -0,0 +1,44 @@
using System.ComponentModel.DataAnnotations;
namespace BBWYB.Server.Model.Dto
{
public class QueryNoCompletionOptimizationTaskRequest : PageRequest
{
/// <summary>
/// 京东SKU
/// </summary>
public string JDSku { get; set; }
/// <summary>
/// 需求方店铺
/// </summary>
public long? BelongShopId { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[Required]
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
[Required]
public DateTime EndTime { get; set; }
/// <summary>
/// SPU优化任务Id
/// </summary>
public long? SpuOptimizationTaskId { get; set; }
/// <summary>
/// Spu或Sku
/// </summary>
public string SpuOrSku { get; set; }
/// <summary>
/// 标题关键字
/// </summary>
public string TitleKeywords { get; set; }
}
}

19
BBWYB.Server.Model/Dto/Request/Order/CompleteOptimizationRequest.cs

@ -0,0 +1,19 @@
namespace BBWYB.Server.Model.Dto
{
public class CompleteOptimizationRequest
{
//public string OrderId { get; set; }
public long ShopId { get; set; }
/// <summary>
/// 店铺SkuId
/// </summary>
public string SkuId { get; set; }
/// <summary>
/// 店铺商品Id
/// </summary>
public string ProductId { get; set; }
}
}

5
BBWYB.Server.Model/Dto/Request/Order/QueryOrderRequest.cs

@ -114,5 +114,10 @@
/// 是否仅显示特殊单,是=1否=0,null则不处理该条件
/// </summary>
public int? IsOnlyDisplaySpecialOrder { get; set; }
/// <summary>
/// 是否需要优化(待议价),仅在订单为等待采购状态有效, 是=1 否=0
/// </summary>
public int? IsNeedOptimization { get; set; }
}
}

9
BBWYB.Server.Model/Dto/Request/PageRequest.cs

@ -0,0 +1,9 @@
namespace BBWYB.Server.Model.Dto
{
public class PageRequest
{
public int PageIndex { get; set; }
public int PageSize { get; set; }
}
}

40
BBWYB.Server.Model/Dto/Request/PurchaseScheme/BatchEditPurchaseSkuActualPriceRequest.cs

@ -0,0 +1,40 @@
namespace BBWYB.Server.Model.Dto
{
public class BatchEditPurchaseSkuActualPriceRequest
{
/// <summary>
/// 可选条件
/// </summary>
public string ProductId { get; set; }
public IList<BatchEditPurchaseSkuActualPriceItemRequest> ItemList { get; set; }
}
public class BatchEditPurchaseSkuActualPriceItemRequest
{
///// <summary>
///// 采购方案Id
///// </summary>
////public long SchemeId { get; set; }
///// <summary>
///// SkuId
///// </summary>
//public string SkuId { get; set; }
/// <summary>
/// 采购SkuId
/// </summary>
public string PurchaseSkuId { get; set; }
/// <summary>
/// 实际单价
/// </summary>
public decimal? ActualPrice { get; set; }
/// <summary>
/// 是否包邮
/// </summary>
public bool? IsFreeFreight { get; set; }
}
}

9
BBWYB.Server.Model/Dto/Request/PurchaseScheme/DeleteSchemeGroupRequest.cs

@ -0,0 +1,9 @@
namespace BBWYB.Server.Model.Dto
{
public class DeleteSchemeGroupFromSpuOptimizationTaskRequest
{
public long SchemeGroupId { get; set; }
public long SpuOptimizationId { get; set; }
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save