From e675033ab6e413f96dc7c73a9fcd0124ce7d8db7 Mon Sep 17 00:00:00 2001 From: shanj <18996038927@163.com> Date: Sat, 3 Jun 2023 00:09:28 +0800 Subject: [PATCH] U --- .../PurchaseOrder/PurchaseOrderBusiness.cs | 74 +++++- .../Sync/OrderSyncBusiness.cs | 8 +- U/APIServices/BaseApiService.cs | 58 +++++ U/APIServices/MdsApiService.cs | 108 +++++++++ U/APIServices/ShopService.cs | 39 ++++ U/App.xaml | 9 + U/App.xaml.cs | 87 +++++++ U/AssemblyInfo.cs | 10 + U/GlobalContext.cs | 26 +++ U/MainWindow.xaml | 26 +++ U/MainWindow.xaml.cs | 216 ++++++++++++++++++ U/MemoryHelper.cs | 49 ++++ .../APIModel/Shop/PurchaseAccountResponse.cs | 19 ++ U/Models/APIModel/Shop/ShopResponse.cs | 86 +++++++ U/Models/APIModel/User/MDSUserResponse.cs | 17 ++ U/Models/Enums.cs | 18 ++ U/Models/MappingProfile.cs | 21 ++ U/Models/NotifyObject.cs | 23 ++ U/Models/Shop/Department.cs | 37 +++ U/Models/Shop/PurchaseAccount.cs | 28 +++ U/Models/Shop/Shop.cs | 89 ++++++++ U/Models/User/User.cs | 33 +++ U/U.csproj | 22 ++ U/WebView2Manager.cs | 69 ++++++ bbwyb.sln | 12 + 25 files changed, 1180 insertions(+), 4 deletions(-) create mode 100644 U/APIServices/BaseApiService.cs create mode 100644 U/APIServices/MdsApiService.cs create mode 100644 U/APIServices/ShopService.cs create mode 100644 U/App.xaml create mode 100644 U/App.xaml.cs create mode 100644 U/AssemblyInfo.cs create mode 100644 U/GlobalContext.cs create mode 100644 U/MainWindow.xaml create mode 100644 U/MainWindow.xaml.cs create mode 100644 U/MemoryHelper.cs create mode 100644 U/Models/APIModel/Shop/PurchaseAccountResponse.cs create mode 100644 U/Models/APIModel/Shop/ShopResponse.cs create mode 100644 U/Models/APIModel/User/MDSUserResponse.cs create mode 100644 U/Models/Enums.cs create mode 100644 U/Models/MappingProfile.cs create mode 100644 U/Models/NotifyObject.cs create mode 100644 U/Models/Shop/Department.cs create mode 100644 U/Models/Shop/PurchaseAccount.cs create mode 100644 U/Models/Shop/Shop.cs create mode 100644 U/Models/User/User.cs create mode 100644 U/U.csproj create mode 100644 U/WebView2Manager.cs diff --git a/BBWYB.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs b/BBWYB.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs index 7ce61d5..6705983 100644 --- a/BBWYB.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs +++ b/BBWYB.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs @@ -25,6 +25,7 @@ namespace BBWYB.Server.Business private FreeSqlMultiDBManager fsqlManager; private OrderBusiness orderBusiness; private VenderBusiness venderBusiness; + private PurchaseSchemeBusiness purchaseSchemeBusiness; private ExpressCompanyNameConverter expressCompanyNameConverter; private RestApiService restApiService; @@ -36,6 +37,7 @@ namespace BBWYB.Server.Business FreeSqlMultiDBManager fsqlManager, OrderBusiness orderBusiness, VenderBusiness venderBusiness, + PurchaseSchemeBusiness purchaseSchemeBusiness, ExpressCompanyNameConverter expressCompanyNameConverter, RestApiService restApiService) : base(fsql, nLogManager, idGenerator) { @@ -46,6 +48,7 @@ namespace BBWYB.Server.Business this.venderBusiness = venderBusiness; this.expressCompanyNameConverter = expressCompanyNameConverter; this.restApiService = restApiService; + this.purchaseSchemeBusiness = purchaseSchemeBusiness; } /// @@ -410,7 +413,7 @@ namespace BBWYB.Server.Business insertOrderCost?.ExecuteAffrows(); if (updatePurchaseTimeSchemeIdList.Count() > 0) fsql.Update(updatePurchaseTimeSchemeIdList).Set(p => p.LastPurchaseTime, DateTime.Now).ExecuteAffrows(); - fsql.Update(request.OrderId).SetIf(dbOrder.OrderState == Enums.OrderState.待付款 || + fsql.Update(request.OrderId).SetIf(dbOrder.OrderState == Enums.OrderState.待付款 || dbOrder.OrderState == Enums.OrderState.等待采购, o => o.OrderState, Model.Enums.OrderState.待出库) .SetIf(!string.IsNullOrEmpty(request.Remark), o => o.PurchaseRemark, request.Remark) .Set(o => o.IsPurchased, true) @@ -488,12 +491,46 @@ namespace BBWYB.Server.Business if (request.AssociationPurchaseOrderList.Any(x => dbInvalidPurchaseOrderIdList.Contains(x.PurchaseOrderId))) throw new BusinessException("关联采购单时不能包含历史采购单"); + #region 读取采购单中的采购账号/采购方案 + IList schemeIdList = new List(); + IList purchaseAccountIdList = request.AssociationPurchaseOrderList.Select(x => string.IsNullOrEmpty(x.PurchaseAccountId) ? + x.PurchaseAccountName : + x.PurchaseAccountId).Distinct().ToList(); + IList purchaseSchemeList = null; + IList dbPurchaseAccountList = null; + foreach (var purchaseOrder in request.AssociationPurchaseOrderList) + { + foreach (var assOrderCostDetail in purchaseOrder.AssocationOrderCostDetailList) + { + if (assOrderCostDetail.PurchaseSchemeId != null) + schemeIdList.Add(assOrderCostDetail.PurchaseSchemeId.Value); + } + } + if (schemeIdList.Count() > 0) + { + purchaseSchemeList = purchaseSchemeBusiness.GetPurchaseSchemeList(new QuerySchemeRequest() + { + ShopId = request.ShopId, + SchemeIdList = schemeIdList + }); + } + if (purchaseAccountIdList.Count() > 0) + { + dbPurchaseAccountList = fsqlManager.MDSfsql.Select().Where(pa => purchaseAccountIdList.Contains(pa.Id) || + purchaseAccountIdList.Contains(pa.AccountName)).ToList(); + } + #endregion + var dbOrderSkuList = fsql.Select().Where(osku => osku.OrderId == request.OrderId).ToList(); var dbOrderCostDetailList = fsql.Select().Where(ocd => ocd.OrderId == request.OrderId && ocd.IsEnabled == true).ToList(); var dbOrderCost = fsql.Select(request.OrderId).ToOne(); var dbOrder = fsql.Select(request.OrderId).ToOne(); + List insertOrderPurchaseInfoList = new List(); + List insertOrderPurchaseSkuInfoList = new List(); + List insertOrderPurchaseRelationInfoList = new List(); + IList> updateOrderPurchaseInfoList = new List>(); List insertOrderCostDetailList = new List(); IList> updateOrderCostDetailList = new List>(); @@ -510,6 +547,32 @@ namespace BBWYB.Server.Business var dbPurchaserOrder = dbPurchaseOrderList.FirstOrDefault(x => x.PurchaseOrderId == purchaseOrder.PurchaseOrderId); if (dbPurchaserOrder == null) { + if (dbPurchaserOrder.PurchasePlatform == Enums.Platform.阿里巴巴) + { + #region 验证新采购单是否具备完整的采购方案 + if (purchaseOrder.AssocationOrderCostDetailList.Any(x => x.PurchaseSchemeId == null)) + throw new BusinessException($"采购单{purchaseOrder.PurchaseOrderId}缺少采购方案"); + #endregion + + #region 验证采购方案和订单详情是否完整 + var purchaseAccount = dbPurchaseAccountList.FirstOrDefault(pa => pa.Id == purchaseOrder.PurchaseAccountId || + pa.AccountName == purchaseOrder.PurchaseAccountName); + if (purchaseAccount == null) + throw new BusinessException($"采购单{purchaseOrder.PurchaseOrderId}缺少有效的采购账号"); + + var client = ppPlatformClientFactory.GetClient((AdapterEnums.PlatformType)purchaseOrder.PurchasePlatform); + var purchaseOrderSimpleInfo = client.QueryOrderDetail(new PP_QueryOrderDetailRequest() + { + AppKey = purchaseAccount.AppKey, + AppSecret = purchaseAccount.AppSecret, + AppToken = purchaseAccount.AppToken, + OrderId = purchaseOrder.PurchaseOrderId + }); + + + #endregion + } + dbPurchaserOrder = new OrderPurchaseInfo() { Id = idGenerator.NewLong(), @@ -530,6 +593,7 @@ namespace BBWYB.Server.Business foreach (var assOrderCostDetail in purchaseOrder.AssocationOrderCostDetailList) { + #region 订单成本 var dbOrderSku = dbOrderSkuList.FirstOrDefault(osku => osku.SkuId == assOrderCostDetail.SkuId); var purchaseFreight = purchaseOrder.PurchaseFreight * (1.0M * assOrderCostDetail.PurchaseQuantity / totalQuantity); var orderCostDetail = new OrderCostDetail() @@ -551,6 +615,7 @@ namespace BBWYB.Server.Business 0M, 0M); insertOrderCostDetailList.Add(orderCostDetail); + #endregion } } else @@ -632,6 +697,11 @@ namespace BBWYB.Server.Business { if (insertOrderPurchaseInfoList.Count() > 0) fsql.Insert(insertOrderPurchaseInfoList).ExecuteAffrows(); + if (insertOrderPurchaseSkuInfoList.Count() > 0) + fsql.Insert(insertOrderPurchaseSkuInfoList).ExecuteAffrows(); + if (insertOrderPurchaseRelationInfoList.Count() > 0) + fsql.Insert(insertOrderPurchaseRelationInfoList).ExecuteAffrows(); + if (updateOrderPurchaseInfoList.Count() > 0) { foreach (var update in updateOrderPurchaseInfoList) @@ -647,7 +717,7 @@ namespace BBWYB.Server.Business insertOrderCost?.ExecuteAffrows(); updateOrderCost?.ExecuteAffrows(); - fsql.Update(dbOrder.Id).SetIf(dbOrder.OrderState == Enums.OrderState.待付款 || + fsql.Update(dbOrder.Id).SetIf(dbOrder.OrderState == Enums.OrderState.待付款 || dbOrder.OrderState == Enums.OrderState.等待采购, o => o.OrderState, Enums.OrderState.待出库) .Set(o => o.IsPurchased, true) .ExecuteAffrows(); diff --git a/BBWYB.Server.Business/Sync/OrderSyncBusiness.cs b/BBWYB.Server.Business/Sync/OrderSyncBusiness.cs index 575356e..96d0a33 100644 --- a/BBWYB.Server.Business/Sync/OrderSyncBusiness.cs +++ b/BBWYB.Server.Business/Sync/OrderSyncBusiness.cs @@ -182,6 +182,7 @@ namespace BBWYB.Server.Business.Sync var updateBuyerRemark = false; var updateVenderRemark = false; var updateBuyerAccount = false; + var updateOrderSn = false; if (dbOrder.OrderState != orderState) updateOrderState = true; @@ -197,8 +198,10 @@ namespace BBWYB.Server.Business.Sync updateVenderRemark = true; if (dbOrder.BuyerAccount != qtOrder.UserAccount) updateBuyerAccount = true; + if (dbOrder.OrderSn != qtOrder.OrderSn) + updateOrderSn = true; - if (updateOrderState || updateModifyTime || updateBuyerRemark || updateVenderRemark || updateBuyerAccount) + if (updateOrderState || updateModifyTime || updateBuyerRemark || updateVenderRemark || updateBuyerAccount || updateOrderSn) { var update = fsql.Update(dbOrder.Id).SetIf(updateOrderState, o => o.OrderState == orderState) //.SetIf(updateWaybillNo, o => o.WaybillNo, qtOrder.DeliveryResponse.WayBillNo) @@ -206,7 +209,8 @@ namespace BBWYB.Server.Business.Sync .SetIf(updateModifyTime, o => o.ModifyTime, qtOrder.ModifyTime) .SetIf(updateBuyerRemark, o => o.BuyerRemark, qtOrder.BuyerRemark) .SetIf(updateVenderRemark, o => o.VenderRemark, qtOrder.VenderRemark) - .SetIf(updateBuyerAccount, o => o.BuyerAccount, qtOrder.UserAccount); + .SetIf(updateBuyerAccount, o => o.BuyerAccount, qtOrder.UserAccount) + .SetIf(updateOrderSn, o => o.OrderSn, qtOrder.OrderSn); updateOrderList.Add(update); } } diff --git a/U/APIServices/BaseApiService.cs b/U/APIServices/BaseApiService.cs new file mode 100644 index 0000000..5a66a3d --- /dev/null +++ b/U/APIServices/BaseApiService.cs @@ -0,0 +1,58 @@ +using BBWYB.Common.Http; +using BBWYB.Common.Models; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Net.Http; + +namespace U.APIServices +{ + public class BaseApiService + { + private RestApiService restApiService; + + protected GlobalContext globalContext; + + public BaseApiService(RestApiService restApiService, GlobalContext globalContext) + { + this.restApiService = restApiService; + this.globalContext = globalContext; + } + + protected ApiResponse SendRequest(string apiHost, + string apiPath, + object param, + IDictionary headers, + HttpMethod httpMethod, + string contentType = RestApiService.ContentType_Json, + ParamPosition paramPosition = ParamPosition.Body, + bool enableRandomTimeStamp = false) + { + try + { + if (headers == null) + headers = new Dictionary(); + if (!headers.ContainsKey("ClientCode")) + headers.Add("ClientCode", "U"); + if (!headers.ContainsKey("ClientVersion")) + headers.Add("ClientVersion", "10000"); + if (!headers.ContainsKey("Authorization") && !string.IsNullOrEmpty(globalContext.UserToken)) + headers.Add("Authorization", $"Bearer {globalContext.UserToken}"); + if (!headers.ContainsKey("qy")) + headers.Add("qy", "qy"); + + var result = restApiService.SendRequest(apiHost, apiPath, param, headers, httpMethod, contentType, paramPosition, enableRandomTimeStamp); + if (result.StatusCode != System.Net.HttpStatusCode.OK && + result.Content.Contains("\"Success\"") && + result.Content.Contains("\"Msg\"") && + result.Content.Contains("\"Data\"")) + throw new BusinessException($"{result.StatusCode} {result.Content}") { Code = (int)result.StatusCode }; + return JsonConvert.DeserializeObject>(result.Content); + } + catch (Exception ex) + { + return ApiResponse.Error((ex is BusinessException) ? (ex as BusinessException).Code : 0, ex.Message); + } + } + } +} diff --git a/U/APIServices/MdsApiService.cs b/U/APIServices/MdsApiService.cs new file mode 100644 index 0000000..4e15b70 --- /dev/null +++ b/U/APIServices/MdsApiService.cs @@ -0,0 +1,108 @@ +using BBWYB.Common.Http; +using BBWYB.Common.Models; +using Newtonsoft.Json.Linq; +using U.Models; +using System; +using System.Collections.Generic; +using System.Net.Http; + +namespace U.APIServices +{ + public class MdsApiService : BaseApiService, IDenpendency + { + public MdsApiService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) + { + + } + + public ApiResponse GetUserInfo(string userToken) + { + return SendRequest(globalContext.MDSApiHost, + "/TaskList/User/GetUserInfo", + null, + new Dictionary() + { + { "Authorization", $"Bearer {userToken}" } + }, HttpMethod.Get); + } + + + + //public ApiResponse> GetShopsByUserTeam(long userId) + //{ + // return SendRequest>(globalContext.MDSApiHost, "TaskList/Shop/GetShopsByUserTeam", $"userId={userId}", null, System.Net.Http.HttpMethod.Get); + //} + + public ApiResponse> GetShopDetailList() + { + var response = new ApiResponse>(); + var response2 = SendRequest(globalContext.MDSApiHost, "TaskList/UserDepartment/GetShopDetailList", null, null, HttpMethod.Get); + if (!response.Success) + { + response.Code = response2.Code; + response.Msg = response2.Msg; + return response; + } + + response.Data = new List(); + foreach (var jDepartment in response2.Data) + { + var jayShops = jDepartment.Value("ShopList"); + if (jayShops == null || !jayShops.HasValues) + continue; //排除空店部门 + var d = new Department() + { + Id = jDepartment.Value("Id"), + Name = jDepartment.Value("DepartmentName") + }; + response.Data.Add(d); + foreach (var jShop in jayShops) + { + if (jShop.Value("ShopId") == null || string.IsNullOrEmpty(jShop.Value("AppToken"))) + continue; //排除未授权 + try + { + var shop = new Shop() + { + ShopId = jShop.Value("ShopId"), + AppKey = jShop.Value("AppKey"), + AppSecret = jShop.Value("AppSecret"), + AppToken = jShop.Value("AppToken"), + ManagePwd = jShop.Value("ManagePwd"), + Platform = (Platform)jShop.Value("PlatformId"), + PlatformCommissionRatio = jShop.Value("PlatformCommissionRatio") ?? 0.05M, + ShopName = jShop.Value("ShopName"), + VenderType = jShop.Value("ShopType"), + TeamId = jShop.Value("TeamId") + }; + d.ShopList.Add(shop); + //var jayAccounts = jShop.Value("AccountList"); + //if (jayAccounts == null || !jayAccounts.HasValues) + // continue; + //shop.PurchaseAccountList = new List(); + //foreach (var jPurchaseAccount in jayAccounts) + //{ + // shop.PurchaseAccountList.Add(new PurchaseAccount() + // { + // Id = jPurchaseAccount.Value("Id"), + // AccountName = jPurchaseAccount.Value("AccountName"), + // AppKey = jPurchaseAccount.Value("AppKey"), + // AppSecret = jPurchaseAccount.Value("AppSecret"), + // AppToken = jPurchaseAccount.Value("AppToken"), + // ShopId = shop.ShopId + // //PurchasePlatformId = jPurchaseAccount.Value() + // }); + //} + } + catch (Exception ex) + { + Console.WriteLine(jShop.ToString()); + throw; + } + } + } + + return response; + } + } +} diff --git a/U/APIServices/ShopService.cs b/U/APIServices/ShopService.cs new file mode 100644 index 0000000..733201c --- /dev/null +++ b/U/APIServices/ShopService.cs @@ -0,0 +1,39 @@ +using BBWYB.Common.Models; +using U.Models; +using System.Collections.Generic; +using System.Net.Http; +using BBWYB.Common.Http; + +namespace U.APIServices +{ + public class ShopService : BaseApiService, IDenpendency + { + public ShopService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) { } + + + /// + /// 获取部门及下属店铺 + /// + /// + public ApiResponse> GetDepartmentList() + { + return SendRequest>(globalContext.BBYWApiHost, "api/vender/GetDeparmentList", null, + new Dictionary() + { + { "bbwyTempKey", "21jfhayu27q" } + }, HttpMethod.Get); + } + + public ApiResponse> GetShopListByIds(IList shopIds) + { + return SendRequest>(globalContext.BBYWApiHost, "api/vender/GetShopListByShopIds", new + { + shopIds + }, new Dictionary() + { + { "bbwyTempKey", "21jfhayu27q" } + }, HttpMethod.Post); + } + + } +} diff --git a/U/App.xaml b/U/App.xaml new file mode 100644 index 0000000..015380c --- /dev/null +++ b/U/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/U/App.xaml.cs b/U/App.xaml.cs new file mode 100644 index 0000000..8401209 --- /dev/null +++ b/U/App.xaml.cs @@ -0,0 +1,87 @@ +using BBWYB.Common.Extensions; +using BBWYB.Common.Http; +using BBWYB.Common.Models; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Windows; +using U.Models; +using Utils; + +namespace U +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + public IServiceProvider ServiceProvider { get; private set; } + public IConfiguration Configuration { get; private set; } + + protected override void OnStartup(StartupEventArgs e) + { + var pjzsExeList = Process.GetProcessesByName("PJZS"); + if (pjzsExeList != null && pjzsExeList.Count() > 1) + { + Environment.Exit(Environment.ExitCode); + } + + var gl = new GlobalContext(); + string userToken = string.Empty; +#if DEBUG + //齐越山鸡 + userToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNTM1MzMwMzI4ODkyMTQ5NzYwIiwidGVhbUlkIjoiMTUxNjk3NDI1MDU0MjUwMTg4OCIsInNvblRlYW1JZHMiOiIxNDM2Mjg4NTAwMjM1MjQzNTIwIiwiZXhwIjoxNjk0NjY5NjkxfQ.cSwro-7bGwOu92YejH9JhMenTai7Mvf99i2paQCmxIw"; +#else + + var tokenResult = ReadMMF(); + if (tokenResult.isOk) + userToken = tokenResult.content; + else + { + MessageBox.Show($"读取内存数据失败\r\n{tokenResult.content}", "提示"); + Environment.Exit(0); + } +#endif + gl.UserToken = userToken; + + + + //var applicationPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + //var builder = new ConfigurationBuilder().SetBasePath(applicationPath).AddJsonFile("appSettings.json", false, true); + //Configuration = builder.Build(); + + //gl.BBYWApiHost = Configuration.GetSection("BBWYApiHost").Value; + //gl.MDSApiHost = Configuration.GetSection("MDSApiHost").Value; + //IServiceCollection serviceCollection = new ServiceCollection(); + //serviceCollection.AddHttpClient(); + + //serviceCollection.AddSingleton(); + //serviceCollection.AddSingleton(gl); + //serviceCollection.BatchRegisterServices(new Assembly[] { Assembly.Load("PJZS") }, typeof(IDenpendency)); + //serviceCollection.AddMapper(new MappingProfile()); + //ServiceProvider = serviceCollection.BuildServiceProvider(); + base.OnStartup(e); + } + + public (bool isOk, string content) ReadMMF() + { + + try + { + var token = MemoryHelper.GetMemoryToken(); + if (string.IsNullOrEmpty(token)) + return (false, "token为空"); + else + return (true, token); + } + catch (Exception ex) + { + return (false, ex.Message); + } + } + } +} diff --git a/U/AssemblyInfo.cs b/U/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/U/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) +)] diff --git a/U/GlobalContext.cs b/U/GlobalContext.cs new file mode 100644 index 0000000..44fb962 --- /dev/null +++ b/U/GlobalContext.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Runtime.InteropServices; + +namespace U +{ + [ClassInterface(ClassInterfaceType.AutoDual)] + [ComVisible(true)] + public class GlobalContext + { + public User User { get; set; } + + public string UserToken { get; set; } + + + #region APIHost + public string BBYWApiHost { get; set; } + + public string MDSApiHost { get; set; } + #endregion + + public string GetUserString() + { + return JsonConvert.SerializeObject(User); + } + } +} \ No newline at end of file diff --git a/U/MainWindow.xaml b/U/MainWindow.xaml new file mode 100644 index 0000000..7e721be --- /dev/null +++ b/U/MainWindow.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/U/MainWindow.xaml.cs b/U/MainWindow.xaml.cs new file mode 100644 index 0000000..6731fb3 --- /dev/null +++ b/U/MainWindow.xaml.cs @@ -0,0 +1,216 @@ +using BBWYB.Common.Extensions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Web.WebView2.Core; +using SJ.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using U.APIServices; + +namespace U +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : BWindow + { + private GlobalContext globalContext; + private WebView2Manager w2m; + private bool isNavigated; + + + private IList managerDepartment; + private MdsApiService mdsApiService; + private ShopService shopService; + public MainWindow() + { + InitializeComponent(); + this.managerDepartment = new List() { "董事办", "财务部", "技术部", "总经办" }; + this.Loaded += MainWindow_Loaded; + this.Closed += MainWindow_Closed; + } + + private void MainWindow_Closed(object sender, EventArgs e) + { + Environment.Exit(Environment.ExitCode); + } + + private bool CheckWebview2Runtime() + { + bool isInstall = false; + try + { + isInstall = !string.IsNullOrEmpty(CoreWebView2Environment.GetAvailableBrowserVersionString()); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + return isInstall; + } + + private void MainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e) + { + if (!CheckWebview2Runtime()) + { + MessageBox.Show("缺少webview2 runtime,请下载安装之后再运行评价助手"); + //下载webview2 runtime + //Task.Factory.StartNew(DownloadWebview2Runtime); + var webview2RuntimeUrl = "https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/238fc310-c6c1-4a3e-a806-4a7c3c17b377/MicrosoftEdgeWebView2RuntimeInstallerX64.exe"; + try + { + System.Diagnostics.Process.Start("explorer.exe", webview2RuntimeUrl); + Thread.Sleep(1000); + } + catch (Exception ex) + { + Clipboard.SetText(webview2RuntimeUrl); + MessageBox.Show($"{ex.Message}\r\n调用浏览器失败,网页链接已复制到剪切板,请手动打开浏览器访问", "提示"); + } + finally + { + Environment.Exit(Environment.ExitCode); + } + } + + //var sp = (App.Current as App).ServiceProvider; + //using (var s = sp.CreateScope()) + //{ + // w2m = s.ServiceProvider.GetRequiredService(); + // //globalContext = s.ServiceProvider.GetRequiredService(); + // //mdsApiService = s.ServiceProvider.GetRequiredService(); + // //shopService = s.ServiceProvider.GetRequiredService(); + //} + + w2m = new WebView2Manager(); + + //Login(); + //txtUserName.Text = globalContext.User.Name; + var url = "http://upc.qiyue666.com/barcode/"; + w2m.CoreWebView2InitializationCompleted = (e) => + { + //w2m.wb2.CoreWebView2.AddHostObjectToScript("uContext", this.globalContext); + isNavigated = true; + w2m.wb2.CoreWebView2.Navigate(url); + }; + + + w2m.Init(); + w2m.wb2.SetValue(Grid.RowProperty, 1); + w2m.wb2.Margin = new Thickness(1, 0, 1, 0); + grid.Children.Add(w2m.wb2); + + + + if (w2m.IsInitializationCompleted && !isNavigated) + { + w2m.wb2.CoreWebView2.Navigate(url); + //w2m.wb2.CoreWebView2.NavigateToString(content); + isNavigated = true; + } + } + + private void Login() + { + try + { + var mdsUserResponse = mdsApiService.GetUserInfo(globalContext.UserToken); + if (!mdsUserResponse.Success) + throw new Exception($"获取磨刀石用户信息失败 {mdsUserResponse.Msg}"); + + globalContext.User = mdsUserResponse.Data.Map(); + globalContext.User.Token = globalContext.UserToken; + globalContext.User.SonDepartmentNames = string.Empty; + if (mdsUserResponse.Data.SonDepartmentList != null && mdsUserResponse.Data.SonDepartmentList.Count > 0) + globalContext.User.SonDepartmentNames = string.Join(',', mdsUserResponse.Data.SonDepartmentList.Select(sd => sd.DepartmentName)); + + IList departmentList = null; + if (globalContext.User.TeamName == "刷单组" || + managerDepartment.Contains(globalContext.User.TeamName) || + managerDepartment.Any(m => globalContext.User.SonDepartmentNames.Contains(m))) + { + var response = shopService.GetDepartmentList(); + if (!response.Success) + throw new Exception(response.Msg); + departmentList = response.Data.Map>(); + } + else + { + var response = mdsApiService.GetShopDetailList(); + if (!response.Success) + throw new Exception(response.Msg); + departmentList = response.Data; + if (departmentList.Count == 0) + throw new Exception("缺少有效的部门数据"); + + var shopIds = new List(); + foreach (var d in departmentList) + { + if (d.ShopList != null && d.ShopList.Count > 0) + { + foreach (var s in d.ShopList) + shopIds.Add(s.ShopId.ToString()); + } + } + + var shopList2Res = shopService.GetShopListByIds(shopIds); + if (shopList2Res.Success && shopList2Res.Data != null && shopList2Res.Data.Count() > 0) + { + foreach (var d in departmentList) + { + foreach (var shop in d.ShopList) + { + var s2 = shopList2Res.Data.FirstOrDefault(s => s.ShopId == shop.ShopId); + if (s2 != null) + { + shop.DingDingKey = s2.DingDingKey; + shop.DingDingWebHook = s2.DingDingWebHook; + shop.SkuSafeTurnoverDays = s2.SkuSafeTurnoverDays; + shop.SiNanPolicyLevel = s2.SiNanPolicyLevel; + shop.SiNanDingDingKey = s2.SiNanDingDingKey; + shop.SiNanDingDingWebHook = s2.SiNanDingDingWebHook; + shop.AppKey2 = s2.AppKey2; + shop.AppSecret2 = s2.AppSecret2; + shop.AppToken2 = s2.AppToken2; + } + } + } + } + } + for (var i = 0; i < departmentList.Count(); i++) + { + var d = departmentList[i]; + for (var j = 0; j < d.ShopList.Count(); j++) + { + var shop = d.ShopList[j]; + if (string.IsNullOrEmpty(shop.AppToken2)) + { + d.ShopList.RemoveAt(j); + j--; + } + } + if (d.ShopList == null || d.ShopList.Count() == 0) + { + departmentList.RemoveAt(i); + i--; + } + + } + globalContext.User.DepartmentList = departmentList; + + } + catch (Exception ex) + { + App.Current.Dispatcher.Invoke(() => + { + MessageBox.Show(ex.Message, "登录失败"); + }); + Environment.Exit(Environment.ExitCode); + } + + } + } +} diff --git a/U/MemoryHelper.cs b/U/MemoryHelper.cs new file mode 100644 index 0000000..f28501d --- /dev/null +++ b/U/MemoryHelper.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.IO.Pipes; + +namespace Utils +{ + public class MemoryHelper + { + /// + /// 获取token + /// + /// + public static string GetMemoryToken() + { + try + { + string pipeId = Environment.GetCommandLineArgs()[1]; + //创建输入类型匿名管道 + using (PipeStream pipeClient = new AnonymousPipeClientStream(PipeDirection.In, pipeId)) + { + using (StreamReader sr = new StreamReader(pipeClient)) + { + string temp; + + do + { + temp = sr.ReadLine(); + } + while (!temp.StartsWith("SYNC")); + + + while ((temp = sr.ReadLine()) != null) + { + return temp; + } + } + } + + return string.Empty; + } + catch (Exception ex) + { + return string.Empty; + } + + } + + } +} diff --git a/U/Models/APIModel/Shop/PurchaseAccountResponse.cs b/U/Models/APIModel/Shop/PurchaseAccountResponse.cs new file mode 100644 index 0000000..9a1b513 --- /dev/null +++ b/U/Models/APIModel/Shop/PurchaseAccountResponse.cs @@ -0,0 +1,19 @@ +namespace U.Models +{ + public class PurchaseAccountResponse + { + public long Id { get; set; } + + public string AccountName { get; set; } + + public long ShopId { get; set; } + + public Platform PurchasePlatformId { get; set; } + + public string AppKey { get; set; } + + public string AppSecret { get; set; } + + public string AppToken { get; set; } + } +} diff --git a/U/Models/APIModel/Shop/ShopResponse.cs b/U/Models/APIModel/Shop/ShopResponse.cs new file mode 100644 index 0000000..c8cae1d --- /dev/null +++ b/U/Models/APIModel/Shop/ShopResponse.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; + +namespace U.Models +{ + public class ShopResponse + { + public string Id { get; set; } + + public Platform PlatformId { get; set; } + + public long? ShopId { get; set; } + + public string ShopName { get; set; } + + public string ShopType { get; set; } + + public string AppKey { get; set; } + + public string AppSecret { get; set; } + + public string AppToken { get; set; } + + public string AppKey2 { get; set; } + + public string AppSecret2 { get; set; } + + public string AppToken2 { get; set; } + + //public IList PurchaseList { get; set; } + + public string ManagePwd { get; set; } + + public decimal? PlatformCommissionRatio { get; set; } + + public string TeamId { get; set; } + + public string TeamName { get; set; } + + public string DingDingWebHook { get; set; } + + public string DingDingKey { get; set; } + + public int SkuSafeTurnoverDays { get; set; } + + /// + /// 司南策略等级 + /// + public int SiNanPolicyLevel { get; set; } + + /// + /// 司南钉钉WebHook地址 + /// + public string SiNanDingDingWebHook { get; set; } + + /// + /// 司南钉钉密钥 + /// + public string SiNanDingDingKey { get; set; } + + /// + /// U钉钉WebHook地址 + /// + public string UDingDingWebHook { get; set; } + + /// + /// U钉钉密钥 + /// + public string UDingDingKey { get; set; } + } + + public class DepartmentResponse + { + public string Id { get; set; } + + public string Name { get; set; } + + public IList ShopList { get; set; } + } + + public class DepartmentResponse2 + { + public string DepartmentId { get; set; } + + public string DepartmentName { get; set; } + } +} diff --git a/U/Models/APIModel/User/MDSUserResponse.cs b/U/Models/APIModel/User/MDSUserResponse.cs new file mode 100644 index 0000000..bc73503 --- /dev/null +++ b/U/Models/APIModel/User/MDSUserResponse.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace U.Models +{ + public class MDSUserResponse + { + public long Id { get; set; } + public string DepartmentName { get; set; } + public string DepartmentId { get; set; } + + public string UserName { get; set; } + + public string UserNick { get; set; } + + public IList SonDepartmentList { get; set; } + } +} diff --git a/U/Models/Enums.cs b/U/Models/Enums.cs new file mode 100644 index 0000000..0f3e0a2 --- /dev/null +++ b/U/Models/Enums.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace U.Models +{ + /// + /// 电商平台 + /// + public enum Platform + { + 淘宝 = 0, + 京东 = 1, + 阿里巴巴 = 2, + 拼多多 = 3, + 微信 = 4 + } +} diff --git a/U/Models/MappingProfile.cs b/U/Models/MappingProfile.cs new file mode 100644 index 0000000..ef79a78 --- /dev/null +++ b/U/Models/MappingProfile.cs @@ -0,0 +1,21 @@ +using AutoMapper; + +namespace U.Models +{ + public class MappingProfile : Profile + { + public MappingProfile() + { + CreateMap().ForMember(t => t.TeamId, opt => opt.MapFrom(f => f.DepartmentId)) + .ForMember(t => t.TeamName, opt => opt.MapFrom(f => f.DepartmentName)) + .ForMember(t => t.Name, opt => opt.MapFrom(f => f.UserName)); + + CreateMap().ForMember(t => t.VenderType, opt => opt.MapFrom(f => f.ShopType)) + .ForMember(t => t.Platform, opt => opt.MapFrom(f => f.PlatformId)); + //.ForMember(t => t.PurchaseAccountList, opt => opt.MapFrom(f => f.PurchaseList)); + + CreateMap(); + CreateMap(); + } + } +} diff --git a/U/Models/NotifyObject.cs b/U/Models/NotifyObject.cs new file mode 100644 index 0000000..5df9a36 --- /dev/null +++ b/U/Models/NotifyObject.cs @@ -0,0 +1,23 @@ +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace U +{ + public class NotifyObject : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName]string propertyName = "") + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected bool Set(ref T oldValue, T newValue, [CallerMemberName]string propertyName = "") + { + if (Equals(oldValue, newValue)) + return false; + oldValue = newValue; + OnPropertyChanged(propertyName); + return true; + } + } +} diff --git a/U/Models/Shop/Department.cs b/U/Models/Shop/Department.cs new file mode 100644 index 0000000..655acd1 --- /dev/null +++ b/U/Models/Shop/Department.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +namespace U +{ + public class Department : NotifyObject + { + private bool isSelected; + + public string Id { get; set; } + + public string Name { get; set; } + + public IList ShopList { get; set; } + public bool IsSelected + { + get => isSelected; + set + { + if (Set(ref isSelected, value)) + OnIsSelectedChanged?.Invoke(); + } + } + + public Department() + { + ShopList = new List(); + } + + public Action OnIsSelectedChanged { get; set; } + + public override string ToString() + { + return this.Name; + } + } +} diff --git a/U/Models/Shop/PurchaseAccount.cs b/U/Models/Shop/PurchaseAccount.cs new file mode 100644 index 0000000..56cca56 --- /dev/null +++ b/U/Models/Shop/PurchaseAccount.cs @@ -0,0 +1,28 @@ +using U.Models; +using System; + +namespace U +{ + public class PurchaseAccount : NotifyObject,ICloneable + { + private string accountName; + private Platform purchasePlatformId; + private string appKey; + private string appSecret; + private string appToken; + + public long Id { get; set; } + + public long ShopId { get; set; } + public string AccountName { get => accountName; set { Set(ref accountName, value); } } + public Platform PurchasePlatformId { get => purchasePlatformId; set { Set(ref purchasePlatformId, value); } } + public string AppKey { get => appKey; set { Set(ref appKey, value); } } + public string AppSecret { get => appSecret; set { Set(ref appSecret, value); } } + public string AppToken { get => appToken; set { Set(ref appToken, value); } } + + public object Clone() + { + return this.MemberwiseClone(); + } + } +} diff --git a/U/Models/Shop/Shop.cs b/U/Models/Shop/Shop.cs new file mode 100644 index 0000000..4c74b78 --- /dev/null +++ b/U/Models/Shop/Shop.cs @@ -0,0 +1,89 @@ +using U.Models; +using System.Collections.Generic; + +namespace U +{ + public class Shop : NotifyObject + { + private bool isSelected; + private string shopName; + + public bool IsSelected { get => isSelected; set { Set(ref isSelected, value); } } + /// + /// 店铺Id + /// + public long ShopId { get; set; } + + /// + /// 商家类型 + /// + public string VenderType { get; set; } + + /// + /// 店铺平台 + /// + public Platform Platform { get; set; } + + public string AppKey { get; set; } + + public string AppSecret { get; set; } + + public string AppToken { get; set; } + + public string AppKey2 { get; set; } + + public string AppSecret2 { get; set; } + + public string AppToken2 { get; set; } + + public string ShopName { get => shopName; set { Set(ref shopName, value); } } + + //public IList PurchaseAccountList { get; set; } + + public string ManagePwd { get; set; } + /// + /// 店铺扣点 + /// + public decimal? PlatformCommissionRatio { get; set; } + + public string TeamId { get; set; } + + public string TeamName { get; set; } + + public string DingDingWebHook { get; set; } + + public string DingDingKey { get; set; } + + public int SkuSafeTurnoverDays { get; set; } + + /// + /// 司南策略等级 + /// + public int SiNanPolicyLevel { get; set; } + + /// + /// 司南钉钉WebHook地址 + /// + public string SiNanDingDingWebHook { get; set; } + + /// + /// 司南钉钉密钥 + /// + public string SiNanDingDingKey { get; set; } + + /// + /// U钉钉WebHook地址 + /// + public string UDingDingWebHook { get; set; } + + /// + /// U钉钉密钥 + /// + public string UDingDingKey { get; set; } + + public override string ToString() + { + return ShopName; + } + } +} diff --git a/U/Models/User/User.cs b/U/Models/User/User.cs new file mode 100644 index 0000000..f94e607 --- /dev/null +++ b/U/Models/User/User.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; + +namespace U +{ + public class User : NotifyObject + { + //private string name; + + private Shop shop; + + public long Id { get; set; } + + public string Name { get; set; } + + public string TeamId { get; set; } + + public string TeamName { get; set; } + + public string SonDepartmentNames { get; set; } + + public Shop Shop { get => shop; set { Set(ref shop, value); } } + + public IList DepartmentList { get; set; } + + /// + /// 店铺列表 (暂时只有刷单组才需要) + /// + public IList ShopList { get; set; } + + public string Token { get; set; } + + } +} diff --git a/U/U.csproj b/U/U.csproj new file mode 100644 index 0000000..3a5cddf --- /dev/null +++ b/U/U.csproj @@ -0,0 +1,22 @@ + + + + WinExe + net6.0-windows + enable + true + + + + + + + + + + + + + + + diff --git a/U/WebView2Manager.cs b/U/WebView2Manager.cs new file mode 100644 index 0000000..7d2241f --- /dev/null +++ b/U/WebView2Manager.cs @@ -0,0 +1,69 @@ +using BBWYB.Common.Models; +using Microsoft.Web.WebView2.Core; +using Microsoft.Web.WebView2.Wpf; +using System; +using io = System.IO; + +namespace U +{ + public class WebView2Manager : IDenpendency + { + public WebView2 wb2 { get; private set; } + //public WebView2Manager() + //{ + // Init(); + //} + public void Init() + { + if (wb2 == null) + { + wb2 = new WebView2(); + var wb2Setting = CoreWebView2Environment.CreateAsync(userDataFolder: io.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "WebView2UserData")).Result; + wb2.EnsureCoreWebView2Async(wb2Setting); + wb2.CoreWebView2InitializationCompleted += Wb2_CoreWebView2InitializationCompleted; + wb2.NavigationCompleted += Wb2_NavigationCompleted; + wb2.WebMessageReceived += Wb2_WebMessageReceived; + } + } + + public Action OnWebMessageReceived; + public Action OnNavigationCompleted; + public Action CoreWebView2InitializationCompleted; + public bool IsInitializationCompleted { get ; private set; } + + private void Wb2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e) + { + OnWebMessageReceived?.Invoke(e); + } + + private void Wb2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e) + { + OnNavigationCompleted?.Invoke(e); + } + + private void Wb2_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) + { + CoreWebView2InitializationCompleted?.Invoke(e); + IsInitializationCompleted = true; + } + + public void Close() + { + if (wb2 != null && wb2.CoreWebView2 != null) + { + IsInitializationCompleted = false; + wb2.CoreWebView2InitializationCompleted -= Wb2_CoreWebView2InitializationCompleted; + wb2.NavigationCompleted -= Wb2_NavigationCompleted; + wb2.WebMessageReceived -= Wb2_WebMessageReceived; + var udf = wb2.CoreWebView2.Environment.UserDataFolder; + wb2.Dispose(); + wb2 = null; + try + { + io.Directory.Delete(udf, true); + } + catch { } + } + } + } +} diff --git a/bbwyb.sln b/bbwyb.sln index 4230397..83bdda8 100644 --- a/bbwyb.sln +++ b/bbwyb.sln @@ -40,6 +40,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Other", "Other", "{878D0106-F55F-4813-9158-F2729D460F9C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "U", "U", "{D34B0974-D525-4BD1-90DE-B2CF5FE47AA4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "U", "U\U.csproj", "{FE3D9812-2D75-4850-8AEA-CE88BAF2F17A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -86,6 +92,10 @@ Global {A4C4F802-D298-42DE-B410-50C8C87EFFAA}.Debug|Any CPU.Build.0 = Debug|Any CPU {A4C4F802-D298-42DE-B410-50C8C87EFFAA}.Release|Any CPU.ActiveCfg = Release|Any CPU {A4C4F802-D298-42DE-B410-50C8C87EFFAA}.Release|Any CPU.Build.0 = Release|Any CPU + {FE3D9812-2D75-4850-8AEA-CE88BAF2F17A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE3D9812-2D75-4850-8AEA-CE88BAF2F17A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE3D9812-2D75-4850-8AEA-CE88BAF2F17A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE3D9812-2D75-4850-8AEA-CE88BAF2F17A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -103,6 +113,8 @@ Global {D5D93778-14D7-45F7-A77C-397FDBA408A1} = {B4ED118A-2CFF-4E8F-B395-608E90C6D0C2} {450F51B1-29E6-47F3-A517-AD5814EC9129} = {B4ED118A-2CFF-4E8F-B395-608E90C6D0C2} {A4C4F802-D298-42DE-B410-50C8C87EFFAA} = {B4ED118A-2CFF-4E8F-B395-608E90C6D0C2} + {D34B0974-D525-4BD1-90DE-B2CF5FE47AA4} = {878D0106-F55F-4813-9158-F2729D460F9C} + {FE3D9812-2D75-4850-8AEA-CE88BAF2F17A} = {D34B0974-D525-4BD1-90DE-B2CF5FE47AA4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0D069898-04B7-4D24-A6A4-D7C703B8BFFC}