From 4db89893f43d4a432c66488fc84ec597a8794f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B5=87=E6=96=87=E9=BE=99?= Date: Fri, 22 Nov 2024 17:51:16 +0800 Subject: [PATCH] =?UTF-8?q?=E9=82=AE=E4=BB=B6=E6=A8=A1=E6=9D=BF=E7=94=9F?= =?UTF-8?q?=E6=88=90=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Enums/TaskPlat/TaskBaseTypeEnum.cs | 6 +- .../DS.Module.Quartz/QuartzModuleInstall.cs | 54 +- .../QuarztJobs/BackgroundTaskJob.cs | 2 +- .../QuarztJobs/FeeCustTemplateJob.cs | 3 - .../DS.WMS.Core/QuarztJobs/PATaskJob.cs | 118 +++ .../Entity/BusinessDataProvider.cs | 9 +- .../Entity/BusinessTaskAttachment.cs | 6 + .../Interface/IMailTemplateService.cs | 31 +- .../Interface/IPreAlertTaskService.cs | 13 +- .../BLConfirm/SubBLConfirmActionExecutor.cs | 2 - .../SpaceReleaseActionExecutor.cs | 1 - .../Method/MailTemplateService.cs | 689 ++++++++++++------ .../Method/PreAlertTaskService.cs | 320 ++++++-- .../TaskInteraction/Method/TaskLogService.cs | 9 +- .../Controllers/SeaExportTaskController.cs | 21 +- .../Controllers/TaskMailController.cs | 54 +- ds-wms-service/DS.WMS.OpApi/appsettings.json | 9 +- 17 files changed, 968 insertions(+), 379 deletions(-) create mode 100644 ds-wms-service/DS.WMS.Core/QuarztJobs/PATaskJob.cs diff --git a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs index 0032f805..a568539f 100644 --- a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs +++ b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs @@ -283,10 +283,10 @@ namespace DS.Module.Core BL_CONFIRMOR_PA = 453, /// - /// 开船通知PA + /// 分单提单确认方PA /// - [Description("开船通知PA")] - DEPARTURE_NOTICE_PA = 454, + [Description("分单提单确认方PA")] + SUB_BL_CONFIRMOR_PA = 454, #endregion #region 基础数据审核 diff --git a/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs b/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs index ffbeb6c9..3ac90a43 100644 --- a/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs +++ b/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs @@ -78,24 +78,21 @@ namespace DS.Module.QuartzModuleInstall /// public static void AddOpQuartzModuleInstall(this IServiceCollection services, IConfiguration configuration) { - int jobCount = 0; - - //var jobKey1 = new JobKey(nameof(WSLReportJob)); - //string cron1 = configuration["JobConfig:" + jobKey1.Name]; - //if (!string.IsNullOrEmpty(cron1)) - //{ - // services.AddQuartz(q => - // { - // q.UseMicrosoftDependencyInjectionJobFactory(); - // q.AddJob(opts => opts.WithIdentity(jobKey1)); - // q.AddTrigger(opts => opts - // .ForJob(jobKey1) - // .WithIdentity(nameof(WSLReportJob) + "-trigger") - // .WithCronSchedule(cron1) - // ); - // }); - // jobCount++; - //} + var jobKey1 = new JobKey(nameof(WSLReportJob)); + string cron1 = configuration["JobConfig:" + jobKey1.Name]; + if (!string.IsNullOrEmpty(cron1)) + { + services.AddQuartz(q => + { + q.UseMicrosoftDependencyInjectionJobFactory(); + q.AddJob(opts => opts.WithIdentity(jobKey1)); + q.AddTrigger(opts => opts + .ForJob(jobKey1) + .WithIdentity(nameof(WSLReportJob) + "-trigger") + .WithCronSchedule(cron1) + ); + }); + } var jobKey2 = new JobKey(nameof(BackgroundTaskJob)); services.AddQuartz(q => @@ -110,8 +107,23 @@ namespace DS.Module.QuartzModuleInstall .WithIntervalInMinutes(5) .RepeatForever())); }); - jobCount++; + var jobKey3 = new JobKey(nameof(PATaskJob)); + string cron3 = configuration["JobConfig:" + jobKey3.Name]; + if (!string.IsNullOrEmpty(cron3)) + { + services.AddQuartz(q => + { + // 配置 Quartz + q.UseMicrosoftDependencyInjectionJobFactory(); + q.AddJob(opts => opts.WithIdentity(jobKey3)); + q.AddTrigger(opts => opts + .ForJob(jobKey3) + .WithIdentity(nameof(PATaskJob) + "-trigger") + .WithCronSchedule(cron3) + ); + }); + } //var jobKey2 = new JobKey(nameof(WSLWeeklyReportJob)); //services.AddQuartz(q => @@ -125,8 +137,8 @@ namespace DS.Module.QuartzModuleInstall // ); //}); - if (jobCount > 0) - services.AddQuartzServer(q => q.WaitForJobsToComplete = true); + // 添加 Quartz 主机服务 + services.AddQuartzServer(q => q.WaitForJobsToComplete = true); } } } diff --git a/ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs b/ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs index 5dc43cd8..583352e2 100644 --- a/ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs +++ b/ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs @@ -45,7 +45,7 @@ namespace DS.WMS.Core.QuarztJobs { if (api.BaseUri == null) { - var baseUrl = configuration["TaskMail:FileBaseUrl"]; + var baseUrl = configuration["TaskMail:OpBaseUrl"]; if (string.IsNullOrEmpty(baseUrl)) { logger.LogInformation("未配置【定时作业触发】请求基础URL"); diff --git a/ds-wms-service/DS.WMS.Core/QuarztJobs/FeeCustTemplateJob.cs b/ds-wms-service/DS.WMS.Core/QuarztJobs/FeeCustTemplateJob.cs index 4768d97f..6744dbf1 100644 --- a/ds-wms-service/DS.WMS.Core/QuarztJobs/FeeCustTemplateJob.cs +++ b/ds-wms-service/DS.WMS.Core/QuarztJobs/FeeCustTemplateJob.cs @@ -48,9 +48,6 @@ namespace DS.WMS.Core.QuarztJobs var dbLinks = await db.Queryable().ToListAsync(); foreach (var dbLink in dbLinks) { - //if (configuration["AutoFeeTemplate:Tenant"] != dbLink.TenantId.ToString()) - // continue; - var adminUser = await db.Queryable() .Where(x => x.TenantId == dbLink.TenantId && x.Status == 0 && x.UserType == 1) .OrderByDescending(x => x.CreateTime) diff --git a/ds-wms-service/DS.WMS.Core/QuarztJobs/PATaskJob.cs b/ds-wms-service/DS.WMS.Core/QuarztJobs/PATaskJob.cs new file mode 100644 index 00000000..60540fcf --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/QuarztJobs/PATaskJob.cs @@ -0,0 +1,118 @@ +using System.Net.Http.Headers; +using DS.Module.Core; +using DS.WMS.Core.Op.Entity; +using DS.WMS.Core.Sys.Entity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Quartz; +using SqlSugar; + +namespace DS.WMS.Core.QuarztJobs +{ + /// + /// PA任务生成 + /// + public sealed class PATaskJob : IJob + { + static readonly ApiFox api; + ISqlSugarClient? db; + IConfiguration configuration; + ILogger logger; + + static PATaskJob() + { + api = new ApiFox(); + } + + /// + /// 初始化 + /// + /// + public PATaskJob(IServiceProvider serviceProvider) + { + db = serviceProvider.GetRequiredService(); + configuration = serviceProvider.GetRequiredService(); + logger = serviceProvider.GetRequiredService>(); + } + + /// + /// 生成PA任务 + /// + /// + /// + public async Task Execute(IJobExecutionContext context) + { + logger.LogInformation("开始运行【PA任务】生成..."); + + db.QueryFilter.Clear(); + var dbLinks = await db.Queryable().ToListAsync(); + foreach (var dbLink in dbLinks) + { + if (dbLink.TenantId.ToString() != configuration["TaskMail:DefaultSetting:Tenant"]) + continue; + + var adminUser = await db.Queryable() + .Where(x => x.TenantId == dbLink.TenantId && x.Status == 0 && x.UserType == 1) + .OrderByDescending(x => x.CreateTime) + .Select(x => new + { + x.Id, + x.UserName, + x.Password, + x.DefaultOrgId, + x.DefaultOrgName, + x.TenantId, + x.TenantName + }).FirstAsync(); + + if (adminUser == null) + { + logger.LogInformation("未能获取租户系统管理员,租户ID:" + dbLink.TenantId); + continue; + } + + var tokenModel = new JwtHelper.JwtTokenModel + { + Uid = adminUser.Id.ToString(), + Name = adminUser.UserName, + OrgId = adminUser.DefaultOrgId.ToString(), + TenantId = adminUser.TenantId.ToString(), + TenantName = adminUser.TenantName + }; + var token = JwtHelper.Encrypt(tokenModel, false, true); + await SendRequestAsync(token); + } + } + + internal async Task SendRequestAsync(string token) + { + if (api.BaseUri == null) + { + var baseUrl = configuration["TaskMail:OpBaseUrl"]; + if (string.IsNullOrEmpty(baseUrl)) + { + logger.LogInformation("未配置【PA任务】请求基础URL"); + return; + } + + api.BaseUri = new Uri(baseUrl, UriKind.Absolute); + } + + api.DefaultHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); + if (!int.TryParse(configuration["TaskMail:DefaultSetting:ETDDays"], out int days)) + days = 3; + + var response = await api.SendRequestAsync(HttpMethod.Post, configuration["TaskMail:PATask"]!, new + { + businessType = (int)BusinessType.OceanShippingExport, + etd = DateTime.Now.Date.AddDays(days) + }); + + if (response.IsSuccessStatusCode) + logger.LogInformation("【PA任务】生成完成..."); + else + logger.LogInformation($"【PA任务】生成失败({response.ToString()}),详情查看日志!"); + } + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessDataProvider.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessDataProvider.cs index adb58ccd..338d993c 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessDataProvider.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessDataProvider.cs @@ -1,4 +1,5 @@ -using SqlSugar; +using DS.WMS.Core.Op.Entity; +using SqlSugar; namespace DS.WMS.Core.TaskInteraction.Entity { @@ -38,6 +39,12 @@ namespace DS.WMS.Core.TaskInteraction.Entity [SugarColumn(ColumnDescription = "数据源内容", IsNullable = true)] public string? Content { get; set; } + /// + /// 业务类型 + /// + [SugarColumn(ColumnDescription = "业务类型")] + public BusinessType BusinessType { get; set; } + /// /// 创建人 /// diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTaskAttachment.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTaskAttachment.cs index be90132a..c4e97870 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTaskAttachment.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTaskAttachment.cs @@ -31,6 +31,12 @@ namespace DS.WMS.Core.TaskInteraction.Entity /// [SugarColumn(ColumnDescription = "文件类型", IsNullable = true)] public FileFormat? FileType { get; set; } + + /// + /// 生成条件 + /// + [SugarColumn(ColumnDescription = "生成条件", ColumnDataType = "longtext", IsNullable = true)] + public string? Condition { get; set; } } /// diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IMailTemplateService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IMailTemplateService.cs index 7ce0895a..699a9f6a 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IMailTemplateService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IMailTemplateService.cs @@ -3,6 +3,7 @@ using DS.Module.Core.Data; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.TaskInteraction.Dtos; using DS.WMS.Core.TaskInteraction.Entity; +using Microsoft.AspNetCore.Mvc; namespace DS.WMS.Core.TaskInteraction.Interface { @@ -82,9 +83,9 @@ namespace DS.WMS.Core.TaskInteraction.Interface /// /// 使用邮件草稿发送邮件 /// - /// 邮件草稿 + /// 邮件草稿ID /// - Task SendAsync(MailDraft draft); + Task SendAsync(long draftId); /// /// 根据任务类型的默认配置创建草稿 @@ -106,6 +107,14 @@ namespace DS.WMS.Core.TaskInteraction.Interface Task> CreateDraftAsync(BusinessTask task, BusinessTaskMail mailConfig, MailTemplateModel? templateModel = null, bool saveDraft = false); + /// + /// 保存邮件草稿 + /// + /// 邮件草稿 + /// 是否保存后发送 + /// + Task SaveDraftAsync(MailDraft draft, bool sendAfterSave); + /// /// 根据业务ID和类型获取模板所需数据 /// @@ -114,5 +123,23 @@ namespace DS.WMS.Core.TaskInteraction.Interface /// 业务类型 /// Task GetBusinessModelAsync(BusinessTaskMail mailConfig, long bsId, BusinessType? bsType = null); + + /// + /// 获取数据提供程序的数据输出 + /// + /// 提供程序ID + /// 业务ID + /// + Task> GetProviderDataAsync(long providerId, long? businessId = null); + + /// + /// 预览邮件模板 + /// + /// 邮件模板ID + /// 业务类型 + /// 编号 + /// + [HttpGet, Route("Preview")] + Task> PreviewAsync(long id, BusinessType businessType, string number); } } diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IPreAlertTaskService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IPreAlertTaskService.cs index 03e0d71d..049af696 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IPreAlertTaskService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/IPreAlertTaskService.cs @@ -1,10 +1,19 @@ -namespace DS.WMS.Core.TaskInteraction.Interface +using DS.Module.Core; +using DS.WMS.Core.Op.Entity; + +namespace DS.WMS.Core.TaskInteraction.Interface { /// /// PA任务 /// public interface IPreAlertTaskService : ITaskService { - + /// + /// 创建PA任务 + /// + /// 业务类型 + /// 出港日期 + /// + Task CreateTaskAsync(BusinessType businessType, DateTime etd); } } diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs index c4b1b2ad..01c48e05 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs @@ -13,7 +13,6 @@ namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm /// public class SubBLConfirmActionExecutor : ServiceBase, IActionExecutor { - //ITaskManageBCService bCService; ISeaExportTaskService taskService; ITaskLogService logService; @@ -23,7 +22,6 @@ namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm /// public SubBLConfirmActionExecutor(IServiceProvider provider) : base(provider) { - //bCService = provider.GetRequiredService(); taskService = provider.GetRequiredService(); logService = provider.GetRequiredService(); } diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/SpaceRelease/SpaceReleaseActionExecutor.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/SpaceRelease/SpaceReleaseActionExecutor.cs index 364f40aa..450fdb41 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/SpaceRelease/SpaceReleaseActionExecutor.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/SpaceRelease/SpaceReleaseActionExecutor.cs @@ -1,5 +1,4 @@ using DS.Module.Core; -using DS.Module.UserModule; using DS.WMS.Core.Info.Interface; using DS.WMS.Core.Op.Interface; using DS.WMS.Core.Sys.Entity; diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailTemplateService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailTemplateService.cs index 6fd9e064..93894519 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailTemplateService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailTemplateService.cs @@ -1,6 +1,10 @@ using System.Collections.Concurrent; +using System.Net.Mail; using System.Reflection; +using Autofac.Core; +using Castle.Core.Resource; using DS.Module.Core; +using DS.Module.Core.Condition; using DS.Module.Core.Data; using DS.Module.Core.Extensions; using DS.Module.PrintModule; @@ -14,8 +18,10 @@ using DS.WMS.Core.TaskInteraction.Entity; using DS.WMS.Core.TaskInteraction.Interface; using Fasterflect; using HtmlAgilityPack; +using LanguageExt.Pretty; using Masuit.Tools; using Masuit.Tools.Systems; +using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -51,6 +57,7 @@ namespace DS.WMS.Core.TaskInteraction.Method readonly IConfiguration config; readonly ILogger logger; + readonly Lazy actionService; /// /// 初始化 @@ -60,9 +67,10 @@ namespace DS.WMS.Core.TaskInteraction.Method { config = provider.GetRequiredService(); logger = provider.GetRequiredService>(); + actionService = new Lazy(provider.GetRequiredService()); Db.QueryFilter.Clear(); - TenantDb.QueryFilter.Clear(); + TenantDb.QueryFilter.Clear(); } /// @@ -252,6 +260,91 @@ namespace DS.WMS.Core.TaskInteraction.Method { var actionManager = ServiceProvider.GetRequiredService(); model.Primary = await actionManager.GetBusinessDataAsync(bsId, bsType.GetValueOrDefault()); + + var custQuery = TenantDb.UnionAll( + TenantDb.Queryable().Where(c => SqlFunc.Subqueryable().Where(s => s.CustomerId == c.Id && s.Id == bsId).Any()) + .Select(c => new InfoClient { Description = c.Description, Note = "controller" }), + TenantDb.Queryable().Where(c => SqlFunc.Subqueryable().Where(s => s.ForwarderId == c.Id && s.Id == bsId).Any()) + .Select(c => new InfoClient { Description = c.Description, Note = "booking" }), + TenantDb.Queryable().Where(c => SqlFunc.Subqueryable().Where(s => s.ShipperCnId == c.Id && s.Id == bsId).Any()) + .Select(c => new InfoClient { Description = c.Description, Note = "shipperCN" }) + ); + var custList = await custQuery.ToListAsync(); + model.CustomerName = custList.Find(x => x.Note == "controller")?.Description ?? string.Empty; + model.ForwarderName = custList.Find(x => x.Note == "booking")?.Description ?? string.Empty; + model.DomesticShipperName = custList.Find(x => x.Note == "shipperCN")?.Description ?? string.Empty; + + var userQuery = TenantDb.UnionAll( + TenantDb.Queryable().InnerJoin((s, u) => s.SaleId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == bsId) + .Select((s, u) => new Contact + { + Code = u.UserCode, + Email = u.Email, + EnName = u.UserEnName, + Name = u.UserName, + Mobile = u.Phone, + Tel = u.OfficePhone, + QQ = u.QQ, + CustomerType = "s" + }), + TenantDb.Queryable().InnerJoin((s, u) => s.SaleId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == bsId) + .Select((s, u) => new Contact + { + Code = u.UserCode, + Email = u.Email, + EnName = u.UserEnName, + Name = u.UserName, + Mobile = u.Phone, + Tel = u.OfficePhone, + QQ = u.QQ, + CustomerType = "o" + }), + TenantDb.Queryable().InnerJoin((s, u) => s.SaleId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == bsId) + .Select((s, u) => new Contact + { + Code = u.UserCode, + Email = u.Email, + EnName = u.UserEnName, + Name = u.UserName, + Mobile = u.Phone, + Tel = u.OfficePhone, + QQ = u.QQ, + CustomerType = "c" + }), + TenantDb.Queryable().InnerJoin((s, u) => s.SaleId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == bsId) + .Select((s, u) => new Contact + { + Code = u.UserCode, + Email = u.Email, + EnName = u.UserEnName, + Name = u.UserName, + Mobile = u.Phone, + Tel = u.OfficePhone, + QQ = u.QQ, + CustomerType = "d" + }) + ); + var userList = await userQuery.ToListAsync(); + model.Sales = userList.Find(x => x.CustomerType == "s"); + model.Operator = userList.Find(x => x.CustomerType == "o"); + model.CustomerService = userList.Find(x => x.CustomerType == "c"); + model.Document = userList.Find(x => x.CustomerType == "d"); + + //获取箱型价格 + model.CtnPriceList = await TenantDb.Queryable().Where(x => x.BusinessId == model.BusinessId) + .Select(x => new BusinessCtnPrice + { + Ctn = x.Ctn, + CtnAll = x.CtnAll, + CtnNum = x.CtnNum, + QuotePrice = x.QuotePrice, + GuidePrice = x.GuidePrice, + FloorPrice = x.FloorPrice + }).ToListAsync(); } else { @@ -282,109 +375,6 @@ namespace DS.WMS.Core.TaskInteraction.Method } } - if (model.Primary == null) - return model; - - List> list = []; - long? forwarderId = null, shipperCNId = null, customerId = null; - var order = model.Primary as SeaExportRes; - order ??= await TenantDb.Queryable().Where(x => x.Id == bsId) - .Select(x => new SeaExportRes - { - SaleId = x.SaleId, - OperatorId = x.OperatorId, - CustomerService = x.CustomerService, - Doc = x.Doc, - ForwarderId = x.ForwarderId, - ShipperCnId = x.ShipperCnId, - CustomerId = x.CustomerId - }).FirstAsync(); - - if (order != null) - { - list.Add(new Tuple(order.SaleId, "sale")); - list.Add(new Tuple(order.OperatorId, "op")); - list.Add(new Tuple(order.CustomerService, "cs")); - list.Add(new Tuple(order.Doc, "doc")); - - forwarderId = order.ForwarderId; - shipperCNId = order.ShipperCnId; - customerId = order.CustomerId; - } - else - { - if (model.Primary is not IDictionary dic) - return model; - - if (dic.TryGetValue(nameof(SeaExport.SaleId), out object? sale)) - list.Add(new Tuple((long)sale, nameof(sale))); - - if (dic.TryGetValue(nameof(SeaExport.OperatorId), out object? op)) - list.Add(new Tuple((long)op, nameof(op))); - - if (dic.TryGetValue(nameof(SeaExport.CustomerService), out object? cs)) - list.Add(new Tuple((long)cs, nameof(cs))); - - if (dic.TryGetValue(nameof(SeaExport.Doc), out object? doc)) - list.Add(new Tuple((long)doc, nameof(doc))); - - if (dic.TryGetValue(nameof(SeaExport.ForwarderId), out object? forwarder) && forwarder != null) - forwarderId = (long)forwarder; - - if (dic.TryGetValue(nameof(SeaExport.ShipperCnId), out object? shipperCN) && shipperCN != null) - shipperCNId = (long)shipperCN; - - if (dic.TryGetValue(nameof(SeaExport.CustomerId), out object? customer) && customer != null) - customerId = (long)customer; - } - - long?[] custIds = [forwarderId, shipperCNId, customerId]; - var custList = await TenantDb.Queryable().Where(x => custIds.Contains(x.Id)) - .Select(x => new { x.Id, x.Description }).ToListAsync(); - model.ForwarderName = custList.Find(x => x.Id == forwarderId)?.Description; - model.DomesticShipperName = custList.Find(x => x.Id == shipperCNId)?.Description; - model.CustomerName = custList.Find(x => x.Id == customerId)?.Description; - - if (list.Count > 0) - { - var ids = list.Select(x => x.Item1).ToArray(); - var userList = await Db.Queryable().Where(x => ids.Contains(x.Id)).Select(x => new Contact - { - Id = x.Id, - Code = x.UserCode, - Email = x.Email, - EnName = x.UserEnName, - Name = x.UserName, - Mobile = x.Phone, - Tel = x.OfficePhone, - QQ = x.QQ - }).ToListAsync(); - - long saleId = list.Find(x => x.Item2 == "sale")!.Item1; - model.Sales = userList.Find(x => x.Id == saleId); - - long opId = list.Find(x => x.Item2 == "op")!.Item1; - model.Operator = userList.Find(x => x.Id == opId); - - long csId = list.Find(x => x.Item2 == "cs")!.Item1; - model.CustomerService = userList.Find(x => x.Id == csId); - - long docId = list.Find(x => x.Item2 == "doc")!.Item1; - model.Document = userList.Find(x => x.Id == docId); - } - - //获取箱型价格 - model.CtnPriceList = await TenantDb.Queryable().Where(x => x.BusinessId == model.BusinessId) - .Select(x => new BusinessCtnPrice - { - Ctn = x.Ctn, - CtnAll = x.CtnAll, - CtnNum = x.CtnNum, - QuotePrice = x.QuotePrice, - GuidePrice = x.GuidePrice, - FloorPrice = x.FloorPrice - }).ToListAsync(); - return model; } @@ -545,6 +535,17 @@ namespace DS.WMS.Core.TaskInteraction.Method } } + /// + /// 使用邮件草稿发送邮件 + /// + /// 邮件草稿ID + /// + public async Task SendAsync(long draftId) + { + var draft = await TenantDb.Queryable().FirstAsync(x => x.Id == draftId); + return await SendAsync(draft); + } + /// /// 使用邮件草稿发送邮件 /// @@ -552,11 +553,26 @@ namespace DS.WMS.Core.TaskInteraction.Method /// public async Task SendAsync(MailDraft draft) { - ArgumentNullException.ThrowIfNull(draft, nameof(draft)); + if (draft == null) + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData)); + + if (string.IsNullOrEmpty(draft.SendTo) || string.IsNullOrEmpty(draft.Account) || string.IsNullOrEmpty(draft.Password) || string.IsNullOrEmpty(draft.Server) || draft.Port <= 0) + return DataResult.Failed("邮件信息不完整,请补全(收件人/发件SMTP配置)后重试"); var mailResult = await Api.SendRequestAsync(HttpMethod.Post, config["TaskMail:MailApiUrl"], draft); if (mailResult.IsSuccessStatusCode) + { + draft.HasSent = true; + draft.UpdateBy = UserId; + draft.UpdateTime = DateTime.Now; + await TenantDb.Updateable(draft).UpdateColumns(x => new + { + x.HasSent, + x.UpdateBy, + x.UpdateTime + }).ExecuteCommandAsync(); return DataResult.Successed($"已发邮件,收件人:" + string.Join(",", draft.SendTo) + "发件人:" + draft.Account); + } return DataResult.Failed($"邮件发送失败,API返回状态为:{(int)mailResult.StatusCode} {mailResult.StatusCode}" + $"收件人:" + string.Join(",", draft.SendTo) + "发件人:" + draft.Account); @@ -589,8 +605,7 @@ namespace DS.WMS.Core.TaskInteraction.Method /// public async Task> CreateDraftAsync(BusinessTask task, MailTemplateModel? templateModel = null, bool saveDraft = false) { - var mailConfig = await TenantDb.Queryable() - .Includes(x => x.Sender).Includes(x => x.Receivers).Includes(x => x.CC).Includes(x => x.Attachments) + var mailConfig = await TenantDb.Queryable().Includes(x => x.Attachments) .Where(x => SqlFunc.Subqueryable().Where(y => x.Id == y.MailId && y.TaskType == task.TaskType && y.IsDefault).Any()) .FirstAsync(); if (mailConfig == null) @@ -614,77 +629,197 @@ namespace DS.WMS.Core.TaskInteraction.Method ArgumentNullException.ThrowIfNull(task, nameof(task)); templateModel ??= await GetBusinessModelAsync(mailConfig, task.BusinessId, task.BusinessType); - var order = await TenantDb.Queryable().Where(x => x.Id == templateModel.BusinessId) - .Select(x => new - { - x.CustomerNo, - x.SaleId, - x.OperatorId, - x.CustomerService, - x.Doc, - x.CarrierId, - x.ForwarderId, - x.YardId, - x.TruckerId, - x.CustomerId - }).FirstAsync(); - if (order == null) - return DataResult.Failed($"未能获取订单({templateModel.BusinessId})数据"); - - //设置发件人 - if (mailConfig.Sender == null) - return DataResult.Failed("未设置发件人"); - - long senderId = 0; - if (mailConfig.Sender.IsSale) - senderId = order.SaleId; - else if (mailConfig.Sender.IsOperator) - senderId = order.OperatorId; - else if (mailConfig.Sender.IsCustomerService) - senderId = order.CustomerService; - else if (mailConfig.Sender.IsVouchingClerk) - senderId = order.Doc; - - templateModel.Sender = await Db.Queryable().Where(x => x.Id == senderId).Select(x => new MailSender - { - DisplayName = x.UserName, - Phone = x.Phone, - SignatureHtml = x.SignatureHtml - }).FirstAsync(); - if (templateModel.Sender == null) - return DataResult.Failed("邮件模板未设置发件人"); - var senderConfig = await TenantDb.Queryable().FirstAsync(x => x.CreateBy == senderId); + var query = TenantDb.UnionAll( + //-----发送人-----// + TenantDb.Queryable() + .InnerJoin((s, u) => s.SaleId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsSale).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "Sender" + }), + TenantDb.Queryable() + .InnerJoin((s, u) => s.OperatorId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsOperator).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "Sender" + }), + TenantDb.Queryable() + .InnerJoin((s, u) => s.CustomerService == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsCustomerService).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "Sender" + }), + TenantDb.Queryable() + .InnerJoin((s, u) => s.Doc == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsVouchingClerk).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "Sender" + }), + //-----抄送人-----// + TenantDb.Queryable() + .InnerJoin((s, u) => s.SaleId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsSale).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "CC" + }), + TenantDb.Queryable() + .InnerJoin((s, u) => s.OperatorId == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsOperator).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "CC" + }), + TenantDb.Queryable() + .InnerJoin((s, u) => s.CustomerService == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsCustomerService).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "CC" + }), + TenantDb.Queryable() + .InnerJoin((s, u) => s.Doc == u.Id, "shippingweb8_dev.sys_user") + .Where((s, u) => s.Id == task.BusinessId && SqlFunc.Subqueryable() + .Where(tms => tms.TaskMailId == mailConfig.Id && tms.IsVouchingClerk).Any()) + .LeftJoin((s, u, um) => u.Id == um.CreateBy) + .Select((s, u, um) => new + { + u.Id, + u.UserName, + u.Phone, + u.Email, + u.SignatureHtml, + um.ShowName, + um.MailAccount, + um.Password, + um.SmtpServer, + um.SmtpPort, + um.SmtpSSL, + UserType = "CC" + }) + ); + + var userList = await query.GroupBy(x => new { x.Id, x.UserType }).ToListAsync(); + var senderConfig = userList.Find(x => x.UserType == "Sender"); if (senderConfig == null) - return DataResult.Failed($"发件人用户:{templateModel.Sender.DisplayName} 未设置SMTP发件信息"); + return DataResult.Failed("邮件模板未设置发件人"); - templateModel.Sender.MailAddress = senderConfig.MailAccount; - List ccList = []; - if (mailConfig.CC != null) + templateModel.Sender = new MailSender { - //设置抄送人 - List ccIds = []; - if (mailConfig.CC.IsSale) - ccIds.Add(order.SaleId); - else if (mailConfig.CC.IsOperator) - ccIds.Add(order.OperatorId); - else if (mailConfig.CC.IsCustomerService) - ccIds.Add(order.CustomerService); - else if (mailConfig.CC.IsVouchingClerk) - ccIds.Add(order.Doc); - - if (ccIds.Count > 0) - ccList = await Db.Queryable().Where(x => ccIds.Contains(x.Id)).Select(x => x.Email).ToListAsync(); - } - - //设置收件人 - if (mailConfig.Receivers == null || mailConfig.Receivers.Count == 0) - return DataResult.Failed("邮件模板未设置收件人"); + DisplayName = senderConfig.UserName, + Phone = senderConfig.Phone, + SignatureHtml = senderConfig.SignatureHtml, + MailAddress = senderConfig.MailAccount + }; + List ccList = userList.Where(x => x.UserType == "CC").Select(x => x.Email).ToList(); - var receiverTypes = mailConfig.Receivers.Select(x => x.Value); - templateModel.Receivers = await TenantDb.Queryable().Where(x => receiverTypes.Contains(x.CustomerType) - && x.Email != null && x.Email != string.Empty && x.BusinessId == templateModel.BusinessId && x.BusinessType == templateModel.BusinessType) - .Select(x => new MailReceiver { DisplayName = x.Name, MailAddress = x.Email }).ToListAsync(); + templateModel.Receivers = await TenantDb.Queryable() + .Where(oc => SqlFunc.Subqueryable().InnerJoin( + (tmr, tm) => tmr.TaskMailId == tm.Id).Where((tmr, tm) => tmr.Value == oc.CustomerType).Any() && + !SqlFunc.IsNullOrEmpty(oc.Email) && oc.BusinessId == templateModel.BusinessId && oc.BusinessType == templateModel.BusinessType) + .Select(oc => new MailReceiver + { + DisplayName = oc.Name, + MailAddress = oc.Email + }).ToListAsync(); + if (templateModel.Receivers.Count == 0) + return DataResult.Failed("邮件模板未设置收件人或订单未填写对应联系人"); string title, content = string.Empty; var razorEngine = new RazorEngine(); @@ -700,17 +835,20 @@ namespace DS.WMS.Core.TaskInteraction.Method } //插入发件人签名 - var htmlDoc = new HtmlDocument(); - htmlDoc.LoadHtml(content); - var node = htmlDoc.GetElementbyId("sign"); - if (node != null) - node.InnerHtml = templateModel.Sender.SignatureHtml; - - using (StringWriter writer = new()) + if (!string.IsNullOrEmpty(templateModel.Sender.SignatureHtml)) { - htmlDoc.Save(writer); - content = writer.ToString(); - writer.Close(); + var htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(content); + var node = htmlDoc.GetElementbyId("sign"); + if (node != null) + node.InnerHtml = templateModel.Sender.SignatureHtml; + + using (StringWriter writer = new()) + { + htmlDoc.Save(writer); + content = writer.ToString(); + writer.Close(); + } } List attaches = mailConfig.Attachments == null ? [] : new List(mailConfig.Attachments.Count); @@ -719,57 +857,68 @@ namespace DS.WMS.Core.TaskInteraction.Method //生成模板附件 if (mailConfig.Attachments?.Count > 0) { - if (Api.DefaultHeaders.Contains("Authorization")) - Api.DefaultHeaders.Remove("Authorization"); - - Api.DefaultHeaders.Add("Authorization", "Bearer " + User.GetToken()); - - long tenantId = long.Parse(User.TenantId); - string requestUrl = config["TaskMail:FileBaseUrl"] + config["TaskMail:SQLPrint"]; object? obj = templateModel.GetPropertyValue(nameof(MailTemplateModel.Primary), Flags.InstancePublic); string json = JsonConvert.SerializeObject(obj ??= new { Id = templateModel.BusinessId }); - - foreach (var item in mailConfig.Attachments) + if (json != "{}" && json != "[]") { - var req = new OpenPrintReq - { - ParamJsonStr = json, - PrintType = ((int)FileFormat.PDF).ToString(), - TemplateId = item.TemplateId, - TenantId = tenantId - }; - var reqResult = await Api.PostAsync(requestUrl, req); - if (!reqResult.Data.Succeeded) - return DataResult.Failed($"未能获取打印API生成的文件,请求地址:{requestUrl}"); - - string url = config["TaskMail:FileBaseUrl"] + @"/PrintTempFile/" + reqResult.Data.Data; - var response = await Api.SendRequestAsync(HttpMethod.Get, url); - if (!response.IsSuccessStatusCode) - return DataResult.Failed($"未能获取打印API生成的文件,附件地址:{url}"); - - string? fileName = Path.GetFileName(reqResult.Data.Data); - if (!string.IsNullOrEmpty(item.FileName)) //设置了文件名 + if (Api.DefaultHeaders.Contains("Authorization")) + Api.DefaultHeaders.Remove("Authorization"); + + Api.DefaultHeaders.Add("Authorization", "Bearer " + User.GetToken()); + string requestUrl = config["TaskMail:PrintBaseUrl"] + config["TaskMail:SQLPrint"]; + long tenantId = long.Parse(User.TenantId); + foreach (var item in mailConfig.Attachments) { - if (item.FileName.Contains('@')) + if (!string.IsNullOrEmpty(item.Condition)) { - fileName = await RenderTemplateAsync(item.FileName, templateModel, razorEngine); + var condition = JsonConvert.DeserializeObject(item.Condition); + if (!actionService.Value.IsMatch(templateModel.Primary, condition)) + continue; } - else + + var req = new OpenPrintReq + { + ParamJsonStr = json, + PrintType = ((int)FileFormat.PDF).ToString(), + TemplateId = item.TemplateId, + TenantId = tenantId + }; + var reqResult = await Api.PostAsync(requestUrl, req); + if (reqResult.Data == null || !reqResult.Data.Succeeded) + return DataResult.Failed($"未能获取打印模板生成的文件,请求地址:{requestUrl}"); + + string url = config["TaskMail:PrintBaseUrl"] + @"/PrintTempFile/" + reqResult.Data.Data; + var response = await Api.SendRequestAsync(HttpMethod.Get, url); + if (!response.IsSuccessStatusCode) + return DataResult.Failed($"未能获取打印模板生成的文件,附件地址:{url}"); + + string? fileName = Path.GetFileName(reqResult.Data.Data); + if (!string.IsNullOrEmpty(item.FileName)) //设置了文件名 { - fileName = item.FileName; + if (item.FileName.Contains('@')) + { + fileName = await RenderTemplateAsync(item.FileName, templateModel, razorEngine); + } + else + { + fileName = item.FileName; + } + + //文件名的最后一个字符不是“.”,则拼接扩展名 + if (item.FileName.LastIndexOf('.') != item.FileName.Length - 1 && item.FileType.HasValue) + fileName = fileName + "." + item.FileType.Value.ToString().ToLowerInvariant(); } - //文件名的最后一个字符不是“.”,则拼接扩展名 - if (item.FileName.LastIndexOf('.') != item.FileName.Length - 1 && item.FileType.HasValue) - fileName = fileName + "." + item.FileType.Value.ToString().ToLowerInvariant(); - } + var byteArray = await response.Content.ReadAsByteArrayAsync(); + //if (byteArray.Length == 0) + // return DataResult.Failed($"打印模板返回了空文件,附件地址:{url}"); - var byteArray = await response.Content.ReadAsByteArrayAsync(); - attaches.Add(new MailDraftAttachment - { - AttachName = fileName, - AttachContent = Convert.ToBase64String(byteArray) - }); + attaches.Add(new MailDraftAttachment + { + AttachName = fileName, + AttachContent = Convert.ToBase64String(byteArray) + }); + } } } @@ -783,9 +932,9 @@ namespace DS.WMS.Core.TaskInteraction.Method Body = content, CCTo = string.Join(";", ccList), ShowName = string.IsNullOrEmpty(senderConfig.ShowName) ? templateModel.Sender.DisplayName : senderConfig.ShowName, - Account = senderConfig.MailAccount, - Password = senderConfig.Password, - Server = senderConfig.SmtpServer, + Account = senderConfig.MailAccount ?? string.Empty, + Password = senderConfig.Password ?? string.Empty, + Server = senderConfig.SmtpServer ?? string.Empty, Port = senderConfig.SmtpPort.GetValueOrDefault(), UseSSL = senderConfig.SmtpSSL.GetValueOrDefault(), Attaches = attaches @@ -802,5 +951,91 @@ namespace DS.WMS.Core.TaskInteraction.Method return DataResult.FailedWithDesc(nameof(MultiLanguageConst.HttpRequestFailed)); } } + + /// + /// 保存邮件草稿 + /// + /// 邮件草稿 + /// 是否保存后发送 + /// + public async Task SaveDraftAsync(MailDraft draft, bool sendAfterSave) + { + if (draft.Id != 0 && await TenantDb.Queryable().AnyAsync(x => x.Id == draft.Id && x.HasSent)) + return DataResult.Failed("禁止编辑已发送的邮件"); + + await TenantDb.Updateable(draft).IgnoreColumns(x => new + { + x.CreateBy, + x.CreateTime, + x.HasSent, + }).ExecuteCommandAsync(); + return sendAfterSave ? await SendAsync(draft) : DataResult.Success; + } + + /// + /// 获取数据提供程序的数据输出 + /// + /// 提供程序ID + /// 业务ID + /// + public async Task> GetProviderDataAsync(long providerId, long? businessId = null) + { + var provider = await TenantDb.Queryable().FirstAsync(x => x.Id == providerId); + if (provider == null) + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData)); + + if (businessId == null) + { + switch (provider.BusinessType) + { + case BusinessType.OceanShippingExport: + businessId = await TenantDb.Queryable().Take(1).OrderBy(x => SqlFunc.GetRandom()).Select(x => x.Id).FirstAsync(); + break; + case BusinessType.OceanShippingImport: + break; + default: + return DataResult.FailedWithDesc(string.Format( + MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BusinessNotSupported)), + provider.BusinessType.GetDescription())); + } + } + + Type? type = Type.GetType(provider.TypeName, true); + var dataProvider = ConstructorExtensions.CreateInstance(type) as IDataProvider; + if (dataProvider == null) + return DataResult.FailedWithDesc("创建数据提供程序失败:" + type.FullName); + + var context = new DataFetchContext + { + BusinessId = businessId, + BusinessType = provider.BusinessType, + Content = provider.Content, + Db = Db, + TenantDb = TenantDb + }; + await dataProvider.FetchDataAsync(context); + return DataResult.Success(context.Data); + } + + /// + /// 预览邮件模板 + /// + /// 邮件模板ID + /// 业务类型 + /// 编号 + /// + [HttpGet, Route("Preview")] + public async Task> PreviewAsync(long id, BusinessType businessType, string number) + { + var mailConfig = (await GetAsync(id))?.Data; + if (mailConfig == null) + return DataResult.Failed($"邮件模板ID:{id} 无效"); + + BusinessTask task = new BusinessTask { BusinessType = businessType }; + task.BusinessId = await TenantDb.Queryable().Where(x => x.CustomerNo == number || x.MBLNO == number) + .Select(x => x.Id).FirstAsync(); + + return await CreateDraftAsync(task, mailConfig, saveDraft: false); + } } } diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/PreAlertTaskService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/PreAlertTaskService.cs index 07ed55dc..cba6b49c 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/PreAlertTaskService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/PreAlertTaskService.cs @@ -1,11 +1,14 @@ using DS.Module.Core; +using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.TaskInteraction.Dtos; using DS.WMS.Core.TaskInteraction.Entity; using DS.WMS.Core.TaskInteraction.Interface; using DS.WMS.Core.TaskPlat.Dtos; using Masuit.Tools.Systems; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using SqlSugar; namespace DS.WMS.Core.TaskInteraction.Method { @@ -16,6 +19,7 @@ namespace DS.WMS.Core.TaskInteraction.Method { IMailTemplateService mailTemplateService; ITaskLogService logService; + IConfiguration config; /// /// 初始化 @@ -25,6 +29,29 @@ namespace DS.WMS.Core.TaskInteraction.Method { mailTemplateService = provider.GetRequiredService(); logService = provider.GetRequiredService(); + config = provider.GetRequiredService(); + } + + /// + /// 创建PA任务 + /// + /// 业务类型 + /// 出港日期 + /// + public async Task CreateTaskAsync(BusinessType businessType, DateTime etd) + { + var ids = await TenantDb.Queryable().Where(x => SqlFunc.DateIsSame(x.ETD, etd)) + .Select(x => x.Id).ToArrayAsync(); + if (ids.Length == 0) + return DataResult.Success; + + TaskCreationRequest request = new() + { + BusinessType = businessType, + Ids = ids, + TaskTypeName = TaskBaseTypeEnum.PRE_ALERT.ToString() + }; + return await CreateMultipleTaskAsync(request); } /// @@ -61,7 +88,6 @@ namespace DS.WMS.Core.TaskInteraction.Method } DataResult result = DataResult.Success; - DateTime dtNow = DateTime.Now; List taskList = []; List subTaskList = []; @@ -70,31 +96,45 @@ namespace DS.WMS.Core.TaskInteraction.Method try { var orders = await TenantDb.Queryable().Where(s => request.Ids.Contains(s.Id)) - .Select((s) => new + .Select(s => new SeaExport { - s.Id, - s.CustomerNo, - s.CustomerId, - s.BLConfirmationId, //提单确认方 - s.AgentId, //国外代理 - s.IssueType, - s.IssuingWay, - s.MBLNO, - s.ETD, - s.Vessel, - s.Voyno, - s.SourceName, - s.SourceDetailName + Id = s.Id, + CustomerNo = s.CustomerNo, + CustomerId = s.CustomerId, + BLConfirmationId = s.BLConfirmationId, //提单确认方 + //s.AgentId, //国外代理 + IssueType = s.IssueType, + IssuingWay = s.IssuingWay, + MBLNO = s.MBLNO, + ETD = s.ETD, + Vessel = s.Vessel, + Voyno = s.Voyno, + SourceName = s.SourceName, + SourceDetailName = s.SourceDetailName + }).ToListAsync(); + var bills = await TenantDb.Queryable().Where(x => request.Ids.Contains(x.BusinessId)) + .Select(x => new SeaExportBillManage + { + Id = x.Id, + BusinessId = x.BusinessId, + HBLNO = x.HBLNO, + BillType = x.BillType, + Vessel = x.Vessel, + Voyno = x.Voyno, + ETD = x.ETD, + //x.BLConfirmationId, + BLIssueStatus = x.BLIssueStatus, + IssueType = x.IssueType }).ToListAsync(); for (int i = 0; i < request.Ids.Length; i++) { + request.BusinessId = request.Ids[i]; var order = orders.Find(s => s.Id == request.BusinessId); if (order == null) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.BusinessNotFound)); - request.BusinessId = request.Ids[i]; - request.TaskTitle = $"【{request.TaskType.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD}|{order.Vessel}|{order.Voyno}"; + request.TaskTitle = $"【{request.TaskType.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD?.ToString("yyyy-MM-dd")} {order.Vessel}|{order.Voyno}"; TaskManageOrderMessageInfo message = await CreateMessageAsync(request); //根据配置获取默认接收人 message.Main.RecvUserInfoList = await GetRecvUsersAsync(request.BusinessId, request.BusinessType, request.TaskType); @@ -109,23 +149,12 @@ namespace DS.WMS.Core.TaskInteraction.Method TaskType = request.TaskType, TaskStatus = TaskStatusEnum.Create, RecvUsers = string.Join(',', message.Main.RecvUserInfoList.Select(x => x.RecvUserId)) ?? string.Empty, - CreateBy = UserId, - CreateTime = dtNow + CreateBy = UserId }); } - await TenantDb.Fastest().BulkCopyAsync(taskList);//保存主任务 + await TenantDb.Insertable(taskList).ExecuteCommandAsync();//保存主任务 - var bills = await TenantDb.Queryable().Where(x => request.Ids.Contains(x.BusinessId)) - .Select(x => new - { - x.Id, - x.HBLNO, - x.BillType, - x.Vessel, - x.Voyno, - x.ETD, - }).ToListAsync(); - foreach (var task in taskList) + foreach (var task in taskList) //创建PA子任务 { var order = orders.Find(s => s.Id == task.BusinessId); var request2 = new TaskCreationRequest //委托单位PA @@ -133,8 +162,10 @@ namespace DS.WMS.Core.TaskInteraction.Method BusinessId = task.BusinessId, BusinessType = task.BusinessType, ParentId = task.Id, + ParentBusinessId = task.BusinessId, + ParentTaskTypeName = task.TaskType.ToString(), TaskTypeName = TaskBaseTypeEnum.CUSTOMER_PA.ToString(), - TaskTitle = $"【{TaskBaseTypeEnum.CUSTOMER_PA.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD}|{order.Vessel}|{order.Voyno}" + TaskTitle = $"【{TaskBaseTypeEnum.CUSTOMER_PA.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD?.ToString("yyyy-MM-dd")}|{order.Vessel}|{order.Voyno}" }; TaskManageOrderMessageInfo message2 = await CreateMessageAsync(request2); //根据配置获取默认接收人 @@ -145,44 +176,50 @@ namespace DS.WMS.Core.TaskInteraction.Method subTaskList.Add(new BusinessTask { - BusinessId = task.BusinessId, - BusinessType = task.BusinessType, - TaskType = request.TaskType, + BusinessId = request2.BusinessId, + BusinessType = request2.BusinessType, + TaskType = request2.TaskType, + ParentBusinessId = request2.ParentBusinessId, + ParentId = task.Id, TaskStatus = TaskStatusEnum.Create, RecvUsers = string.Join(',', message2.Main.RecvUserInfoList.Select(x => x.RecvUserId)) ?? string.Empty, - CreateBy = UserId, - CreateTime = dtNow + CreateBy = UserId }); - if ((order.SourceName != "CIF-自揽货" && order.SourceDetailName != "WSL Member") || (order.SourceName != "CIF-自揽货" && order.SourceDetailName != "国外同行")) + //订单来源不等于WSL指定货且来源明细不等于WSL Member/国外同行则生成【国外代理PA】任务 + if ((order.SourceName != "WSL指定货" && order.SourceDetailName != "WSL Member") || (order.SourceName != "CIF-自揽货" && order.SourceDetailName != "国外同行")) { var request3 = new TaskCreationRequest //国外代理PA { BusinessId = task.BusinessId, BusinessType = task.BusinessType, ParentId = task.Id, + ParentBusinessId = task.BusinessId, + ParentTaskTypeName = task.TaskType.ToString(), TaskTypeName = TaskBaseTypeEnum.FOREIGN_AGENCY_PA.ToString(), - TaskTitle = $"【{TaskBaseTypeEnum.FOREIGN_AGENCY_PA.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD}|{order.Vessel}|{order.Voyno}" + TaskTitle = $"【{TaskBaseTypeEnum.FOREIGN_AGENCY_PA.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD?.ToString("yyyy-MM-dd")} {order.Vessel}|{order.Voyno}" }; TaskManageOrderMessageInfo message3 = await CreateMessageAsync(request3); //根据配置获取默认接收人 - message2.Main.RecvUserInfoList = await GetRecvUsersAsync(request3.BusinessId, request3.BusinessType, request3.TaskType); + message3.Main.RecvUserInfoList = await GetRecvUsersAsync(request3.BusinessId, request3.BusinessType, request3.TaskType); result = await ManagerService.InitTaskJob(message3); if (!result.Succeeded) return result; subTaskList.Add(new BusinessTask { - BusinessId = task.BusinessId, - BusinessType = task.BusinessType, - TaskType = request.TaskType, + BusinessId = request3.BusinessId, + BusinessType = request3.BusinessType, + TaskType = request3.TaskType, + ParentBusinessId = request3.ParentBusinessId, + ParentId = task.Id, TaskStatus = TaskStatusEnum.Create, RecvUsers = string.Join(',', message3.Main.RecvUserInfoList.Select(x => x.RecvUserId)) ?? string.Empty, - CreateBy = UserId, - CreateTime = dtNow + CreateBy = UserId }); } + //订单签单方式=直单且委托单位不等于提单确认人则生成【提单确认方PA】任务 if (order.IssuingWay == "zd" && order.CustomerId != order.BLConfirmationId) { var request4 = new TaskCreationRequest //提单确认方PA @@ -190,44 +227,80 @@ namespace DS.WMS.Core.TaskInteraction.Method BusinessId = task.BusinessId, BusinessType = task.BusinessType, ParentId = task.Id, + ParentBusinessId = task.BusinessId, + ParentTaskTypeName = task.TaskType.ToString(), TaskTypeName = TaskBaseTypeEnum.BL_CONFIRMOR_PA.ToString(), - TaskTitle = $"【{TaskBaseTypeEnum.BL_CONFIRMOR_PA.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD}|{order.Vessel}|{order.Voyno}" + TaskTitle = $"【{TaskBaseTypeEnum.BL_CONFIRMOR_PA.GetDescription()}】{order.CustomerNo} {order.MBLNO} {order.ETD?.ToString("yyyy-MM-dd")}|{order.Vessel}|{order.Voyno}" }; TaskManageOrderMessageInfo message4 = await CreateMessageAsync(request4); //根据配置获取默认接收人 - message2.Main.RecvUserInfoList = await GetRecvUsersAsync(request4.BusinessId, request4.BusinessType, request4.TaskType); + message4.Main.RecvUserInfoList = await GetRecvUsersAsync(request4.BusinessId, request4.BusinessType, request4.TaskType); result = await ManagerService.InitTaskJob(message4); if (!result.Succeeded) return result; subTaskList.Add(new BusinessTask { - BusinessId = task.BusinessId, - BusinessType = task.BusinessType, - TaskType = request.TaskType, + BusinessId = request4.BusinessId, + BusinessType = request4.BusinessType, + TaskType = request4.TaskType, + ParentBusinessId = request4.ParentBusinessId, + ParentId = task.Id, TaskStatus = TaskStatusEnum.Create, RecvUsers = string.Join(',', message4.Main.RecvUserInfoList.Select(x => x.RecvUserId)) ?? string.Empty, + CreateBy = UserId + }); + } + + var subBills = bills.FindAll(x => x.BusinessId == order.Id); + foreach (var bill in subBills) + { + var billRequest = new TaskCreationRequest //分单提单确认方PA + { + BusinessId = bill.Id, + BusinessType = task.BusinessType, + ParentId = task.Id, + ParentBusinessId = task.BusinessId, + ParentTaskTypeName = task.TaskType.ToString(), + TaskTypeName = TaskBaseTypeEnum.SUB_BL_CONFIRMOR_PA.ToString(), + TaskTitle = $"【{TaskBaseTypeEnum.SUB_BL_CONFIRMOR_PA.GetDescription()}】{bill.HBLNO} {bill.BillType} {bill.ETD?.ToString("yyyy-MM-dd")}|{bill.Vessel}|{bill.Voyno}" + }; + TaskManageOrderMessageInfo billMessage = await CreateMessageAsync(billRequest); + //根据配置获取默认接收人 + billMessage.Main.RecvUserInfoList = await GetRecvUsersAsync(billRequest.BusinessId, billRequest.BusinessType, billRequest.TaskType); + result = await ManagerService.InitTaskJob(billMessage); + if (!result.Succeeded) + return result; + + subTaskList.Add(new BusinessTask + { + BusinessId = billRequest.BusinessId, + BusinessType = billRequest.BusinessType, + TaskType = billRequest.TaskType, + ParentBusinessId = billRequest.ParentBusinessId, + ParentId = task.Id, + TaskStatus = TaskStatusEnum.Create, + RecvUsers = string.Join(',', billMessage.Main.RecvUserInfoList.Select(x => x.RecvUserId)) ?? string.Empty, CreateBy = UserId, - CreateTime = dtNow }); } } - await TenantDb.Fastest().BulkCopyAsync(subTaskList);//保存子任务 + await TenantDb.Insertable(subTaskList).ExecuteCommandAsync();//保存子任务 var allTasks = taskList.Union(subTaskList).ToArray(); - await logService.WriteLogAsync(string.Empty, allTasks); - + await logService.WriteLogAsync(string.Empty, allTasks); //写入日志 var unionIds = orders.Select(x => x.Id).Union(bills.Select(x => x.Id)); //合并订单ID与分单ID - var opFiles = await TenantDb.Queryable().Where(x => unionIds.Contains(x.LinkId)) - .Select(x => new + var opFiles = await TenantDb.Queryable().Where(x => unionIds.Contains(x.LinkId)) //拉取附件 + .Select(x => new OpFile { - x.LinkId, - x.TypeCode, - x.FileName, - x.FilePath + LinkId = x.LinkId, + TypeCode = x.TypeCode, + FileName = x.FileName, + FilePath = x.FilePath }).ToListAsync(); + List mailDrafts = []; - foreach (var task in subTaskList) + foreach (var task in subTaskList) //添加子任务附件 { var draftResult = await mailTemplateService.CreateDraftAsync(task); if (!draftResult.Succeeded) @@ -236,29 +309,51 @@ namespace DS.WMS.Core.TaskInteraction.Method continue; } - draftResult.Data.TaskId = task.Id; var order = orders.Find(x => x.Id == task.BusinessId); - string typeCode = string.Empty; - switch (order.IssueType) + var billList = bills.FindAll(x => x.Id == task.BusinessId); + draftResult.Data.TaskId = task.Id; + if (task.TaskType == TaskBaseTypeEnum.SUB_BL_CONFIRMOR_PA) //分单子任务 { - case "正本": - typeCode = "OringinalBill_Mbl"; //正本提单扫描件 - break; - - case "SWB": - typeCode = "swb"; - break; - - case "EBL": - typeCode = "OringinalBill_Mbl"; - break; + result = AddHBLAttachments(opFiles, billList, draftResult.Data); + if (!result.Succeeded) + await logService.WriteLogAsync(task, result.Message); } - var opFile = opFiles.Find(x => x.LinkId == order.Id && x.TypeCode == typeCode); - opFile ??= opFiles.Find(x => x.LinkId == order.Id && x.TypeCode == "format_sheet"); - - if (opFile == null) //获取不到订单附件则记录错误日志 - { + else //主单子任务 + { + //订单类型为分单时,只需要有分单格式件和账单;为直单且来源明细为“国外同行、国外直客”时,需要有主单格式件和账单,其余情况生成账单 + if (task.TaskType == TaskBaseTypeEnum.CUSTOMER_PA) + { + if (order.IssuingWay == "fd") + { + result = AddHBLAttachments(opFiles, billList, draftResult.Data); + if (!result.Succeeded) + await logService.WriteLogAsync(task, result.Message); + } + else if (order.IssuingWay == "zd" && (order.SourceDetailName == "国外同行" || order.SourceDetailName == "国外直客")) + { + result = AddMBLAttachment(opFiles, order, draftResult.Data); + if (!result.Succeeded) + await logService.WriteLogAsync(task, result.Message); + } + } + //主单格式件+分单格式件(有分单时)+账单 + else if (task.TaskType == TaskBaseTypeEnum.FOREIGN_AGENCY_PA) + { + result = AddMBLAttachment(opFiles, order, draftResult.Data); + if (!result.Succeeded) + await logService.WriteLogAsync(task, result.Message); + result = AddHBLAttachments(opFiles, billList, draftResult.Data); + if (!result.Succeeded) + await logService.WriteLogAsync(task, result.Message); + } + //主单格式单和账单 + else if (task.TaskType == TaskBaseTypeEnum.BL_CONFIRMOR_PA) + { + result = AddMBLAttachment(opFiles, order, draftResult.Data); + if (!result.Succeeded) + await logService.WriteLogAsync(task, result.Message); + } } mailDrafts.Add(draftResult.Data); @@ -282,5 +377,70 @@ namespace DS.WMS.Core.TaskInteraction.Method } } + //添加MBL格式件 + static DataResult AddMBLAttachment(List opFiles, SeaExport order, MailDraft draft) + { + string? typeCode = null; + switch (order.IssueType) + { + case "正本": + typeCode = "OringinalBill_Mbl"; //正本提单扫描件 + break; + + case "SWB": + typeCode = "swb"; + break; + + case "EBL": + typeCode = "OringinalBill_Mbl"; + break; + } + var opFile = opFiles.Find(x => x.LinkId == order.Id && x.TypeCode == typeCode); + if (opFile == null) + { + typeCode = "format_sheet"; + opFile = opFiles.Find(x => x.LinkId == order.Id && x.TypeCode == typeCode); + } + + if (opFile == null) //获取不到订单附件则记录错误日志 + return DataResult.Failed($"未能从订单 {order.CustomerNo} 中获取类型为 {typeCode} 的附件"); + + MailDraftAttachment attachment = new() + { + DraftId = draft.Id, + AttachName = opFile.FileName, + UrlPath = opFile.FilePath + }; + draft.Attaches.Add(attachment); + return DataResult.Success; + } + + //添加HBL格式件 + static DataResult AddHBLAttachments(List opFiles, List bills, MailDraft draft) + { + string? typeCode = null; + foreach (var bill in bills) + { + if (bill.BLIssueStatus == (int)BLIssueStatusEnum.CheckOut) //已签发 + { + if (bill.IssueType != "正本" && bill.IssueType != "电放" && bill.IssueType != "SWB" && bill.IssueType != "EBL") + typeCode = "Original(HBL)"; + } + + var opFile = opFiles.Find(x => x.LinkId == bill.Id && x.TypeCode == typeCode); + if (opFile != null) + { + MailDraftAttachment attachment = new() + { + DraftId = draft.Id, + AttachName = opFile.FileName, + UrlPath = opFile.FilePath + }; + draft.Attaches.Add(attachment); + } + } + + return DataResult.Success; + } } } diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskLogService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskLogService.cs index a6284176..23574f91 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskLogService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskLogService.cs @@ -129,7 +129,14 @@ namespace DS.WMS.Core.TaskInteraction.Method { ArgumentNullException.ThrowIfNull(logs, nameof(logs)); - await TenantDb.Insertable(logs).ExecuteCommandAsync(); + if (logs.Length > 100) + { + await TenantDb.Fastest().BulkCopyAsync([.. logs]); + } + else + { + await TenantDb.Insertable(logs).ExecuteCommandAsync(); + } } } } diff --git a/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs b/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs index cc5200f0..0c8f2c10 100644 --- a/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs +++ b/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs @@ -36,8 +36,8 @@ namespace DS.WMS.OpApi.Controllers /// /// /GetTasks?taskTypes=任务类型1&taskTypes=任务类型2 [HttpGet, Route("GetTasks")] - public async Task>> GetTasksAsync(long businessId, BusinessType? businessType, - bool withSubTask = false, params string[] taskTypes) + public async Task>> GetTasksAsync(long businessId, BusinessType? businessType, + bool withSubTask = false, params string[] taskTypes) { TaskBaseTypeEnum[]? types = null; if (taskTypes?.Length > 0) @@ -53,7 +53,7 @@ namespace DS.WMS.OpApi.Controllers /// 业务类型(可选参数) /// [HttpGet, Route("GetBLConfirmation")] - public async Task> GetBLConfirmationAsync(long businessId, BusinessType businessType) + public async Task> GetBLConfirmationAsync(long businessId, BusinessType businessType) { return await taskService.GetBLConfirmationAsync(businessId, businessType); } @@ -288,5 +288,20 @@ namespace DS.WMS.OpApi.Controllers await taskService.RunJobAsync(); return StatusCode((int)HttpStatusCode.NoContent); } + + /// + /// 创建PA任务 + /// + /// + /// 业务类型 + /// 出港日期 + /// + [HttpPost, Route("CreatePATask")] + public async Task CreatePATaskAsync([FromServices] IPreAlertTaskService paTaskService, + BusinessType businessType = BusinessType.OceanShippingExport, DateTime? etd = null) + { + etd ??= DateTime.Now.Date; + return await paTaskService.CreateTaskAsync(businessType, etd.Value); + } } } diff --git a/ds-wms-service/DS.WMS.OpApi/Controllers/TaskMailController.cs b/ds-wms-service/DS.WMS.OpApi/Controllers/TaskMailController.cs index 7dfaf6b9..2f72be99 100644 --- a/ds-wms-service/DS.WMS.OpApi/Controllers/TaskMailController.cs +++ b/ds-wms-service/DS.WMS.OpApi/Controllers/TaskMailController.cs @@ -1,5 +1,6 @@ using DS.Module.Core; using DS.Module.Core.Data; +using DS.WMS.Core.Op.Entity; using DS.WMS.Core.TaskInteraction.Entity; using DS.WMS.Core.TaskInteraction.Interface; using Microsoft.AspNetCore.Mvc; @@ -22,35 +23,18 @@ namespace DS.WMS.OpApi.Controllers this.service = service; } - ///// - ///// 预览邮件模板 - ///// - ///// - ///// 委托编号 - ///// 单据类型 - ///// 模板自定义名称 - ///// - //[HttpGet, Route("Preview")] - //public async Task PreviewAsync([FromServices] IHostEnvironment host, string customerNO, DocumentType docType, string? templateName = null) - //{ - // var result = await service.GetMailContentAsync(customerNO, docType, templateName); - // if (!result.Succeeded) - // return Content(result.Message); - - // //string dir = Path.Combine(host.ContentRootPath, "wwwroot", "content-preview"); - // //if (!Directory.Exists(dir)) - // // Directory.CreateDirectory(dir); - - // //string path = Path.Combine(dir, customerNO + ".htm"); - // //FileStream fs = new FileStream(path, FileMode.Create); - // //StreamWriter writer = new StreamWriter(fs, Encoding.UTF8); - // //await writer.WriteAsync(result.Data.Item2); - // //await fs.FlushAsync(); - - // //return PhysicalFile(path, "application/octet-stream"); - - // return File(Encoding.UTF8.GetBytes(result.Data.Item2), "application/octet-stream", customerNO + ".htm"); - //} + /// + /// 预览邮件模板 + /// + /// 邮件模板ID + /// 业务类型 + /// 委托编号/提单号 + /// + [HttpGet, Route("Preview")] + public async Task> PreviewAsync([FromQuery] long id, [FromQuery] BusinessType businessType, [FromQuery] string number) + { + return await service.PreviewAsync(id, businessType, number); + } /// /// 获取数据提供程序 @@ -63,6 +47,18 @@ namespace DS.WMS.OpApi.Controllers return await service.GetProvidersAsync(queryKey); } + /// + /// 获取数据提供程序的数据输出 + /// + /// 提供程序ID + /// 业务ID(不指定此参数则随机获取) + /// + [HttpGet, Route("GetProviderData")] + public async Task> GetProviderData([FromQuery] long providerId, [FromQuery] long? businessId = null) + { + return await service.GetProviderDataAsync(providerId, businessId); + } + /// /// 获取分页列表 /// diff --git a/ds-wms-service/DS.WMS.OpApi/appsettings.json b/ds-wms-service/DS.WMS.OpApi/appsettings.json index 568ce576..e10e6398 100644 --- a/ds-wms-service/DS.WMS.OpApi/appsettings.json +++ b/ds-wms-service/DS.WMS.OpApi/appsettings.json @@ -107,14 +107,17 @@ "ResultUrl": "http://47.104.73.97:7115/api/TaskShippingOrderCompare/CompareResult" }, "TaskMail": { - "FileBaseUrl": "http://localhost:5030", + "PrintBaseUrl": "http://118.190.144.189:3008", "JsonPrint": "/printApi/OpenPrint/GetOpenJsonPrintInfoAsync", "JsonPrintByCode": "/printApi/OpenPrint/GetOpenJsonPrintInfoByTemplateCode", "SQLPrint": "/printApi/OpenPrint/GetOpenSqlPrintInfo", + "OpBaseUrl": "http://localhost:5030", "RunJob": "/opApi/SeaExportTask/RunJob", + "PATask": "/opApi/SeaExportTask/CreatePATask", "LinkAttach": "http://118.190.144.189:3008/LinkAttach", "MailApiUrl": "http://47.104.73.97:8801/mail/send", "DefaultSetting": { + "ETDDays": 3, "Tenant": 1750335377144680448, "Account": "lyle@yyts.fun", "Password": "15275215387jZ", @@ -146,8 +149,8 @@ "FileType": [ ".xls", ".xlsx" ] }, "JobConfig": { - "WSLReportJob": "0 0 17 * * ?", - //"WSLWeeklyReportJob": "0 30 16 * * ?" , + //"WSLReportJob": "0 0 17 * * ?", + "PATaskJob": "0 30 5 * * ?", "WSLWeeklyReportJob": "0 */1 * * * ?" } }