From 56542f015e967820581f4112807ade69fd4a4101 Mon Sep 17 00:00:00 2001 From: jianghaiqing Date: Fri, 21 Apr 2023 14:55:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B4=BE=E8=BD=A6=E6=89=93?= =?UTF-8?q?=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Enum/PrintFileTypeEnum.cs | 31 ++ Myshipping.Application/Helper/PrintHelper.cs | 173 +++++++ .../BookingTruck/BookingTruckService.cs | 375 ++++++++++++++- .../Interface/IBookingTruckService.cs | 19 +- .../Interface/ITaskManageTruckService.cs | 27 +- .../TaskManagePlat/TaskManageTruckService.cs | 437 +++++++++++++++++- 6 files changed, 1038 insertions(+), 24 deletions(-) create mode 100644 Myshipping.Application/Enum/PrintFileTypeEnum.cs create mode 100644 Myshipping.Application/Helper/PrintHelper.cs diff --git a/Myshipping.Application/Enum/PrintFileTypeEnum.cs b/Myshipping.Application/Enum/PrintFileTypeEnum.cs new file mode 100644 index 00000000..cc87866b --- /dev/null +++ b/Myshipping.Application/Enum/PrintFileTypeEnum.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// 打印文件类型枚举 + /// + public enum PrintFileTypeEnum + { + /// + /// pdf + /// + [Description("pdf")] + PDF = 1, + /// + /// xlsx + /// + [Description("xlsx")] + XLSX = 2, + /// + /// docx + /// + [Description("docx")] + DOCX = 3 + } +} diff --git a/Myshipping.Application/Helper/PrintHelper.cs b/Myshipping.Application/Helper/PrintHelper.cs new file mode 100644 index 00000000..02976b39 --- /dev/null +++ b/Myshipping.Application/Helper/PrintHelper.cs @@ -0,0 +1,173 @@ +using Furion; +using Furion.FriendlyException; +using Furion.JsonSerialization; +using Furion.Logging; +using Furion.RemoteRequest.Extensions; +using Microsoft.Extensions.Logging; +using Myshipping.Application.ConfigOption; +using Myshipping.Application.Entity; +using Myshipping.Application.Enum; +using Myshipping.Core; +using Newtonsoft.Json.Linq; +using NPOI.HPSF; +using Org.BouncyCastle.Asn1.X500; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using static System.Net.WebRequestMethods; + +namespace Myshipping.Application +{ + public static class PrintHelper + { + public static async Task GeneratePrintFile(string BusiJson,string reportUrl, PrintFileTypeEnum printFileType, + BookingPrintTemplate printTemplate) + { + var logger = Log.CreateLogger(nameof(PrintHelper)); + + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + + //根据部署环境选择替换文件路径 + var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + fileAbsPath = fileAbsPath.Replace("\\", "/"); + } + else + { + fileAbsPath = fileAbsPath.Replace("/", "\\"); + } + + + if (!System.IO.File.Exists(fileAbsPath)) + { + logger.LogInformation("模板文件不存在 path={path}", fileAbsPath); + + throw Oops.Bah("模板文件不存在"); + } + + System.IO.FileStream file = new System.IO.FileStream(fileAbsPath, FileMode.Open, FileAccess.Read); + int SplitSize = 5242880;//5M分片长度 + int index = 1; //序号 第几片 + long StartPosition = 5242880 * (index - 1); + long lastLens = file.Length - StartPosition;//真不知道怎么起命了,就这样吧 + if (lastLens < 5242880) + { + SplitSize = (int)lastLens; + } + byte[] heByte = new byte[SplitSize]; + file.Seek(StartPosition, SeekOrigin.Begin); + //第一个参数是 起始位置 + file.Read(heByte, 0, SplitSize); + //第三个参数是 读取长度(剩余长度) + file.Close(); + + NameValueCollection par = new NameValueCollection(); + par.Add("printType", ((int)printFileType).ToString()); + par.Add("dataJson", BusiJson); + + var rtn = TransmitFile(reportUrl, par, new { + file = "file", + fileName = printTemplate.FileName, + fileBytes = heByte + }); + + var jobjRtn = JObject.Parse(rtn); + logger.LogInformation($"调用报表生成返回:{rtn}"); + + if (jobjRtn.GetBooleanValue("Success")) + { + //调用读取文件 + var fn = jobjRtn.GetStringValue("Data"); + //logger.LogInformation($"准备调用读取报表文件:id:{bookingId},文件名:{fn}"); + var readFileUrl = $"{reportUrl}Report/GetFile?fileName={fn}"; + var bs = await readFileUrl.GetAsByteArrayAsync(); + + logger.LogInformation($"调用读取报表文件返回:{bs.Length}"); + + return bs; + } + else + { + throw Oops.Bah($"生成报表文件失败:{jobjRtn.GetStringValue("Message")}"); + } + } + + #region 请求打印生成文件 + /// + /// 请求打印生成文件 + /// + /// 请求接口地址 + /// 键值对参数 + /// 文件信息 + /// 默认 application/json + /// 返回结果 + public static string TransmitFile(string requestUrl, NameValueCollection nameValueCollection, dynamic fileInfo, + string contentType = "application/json") + { + var result = string.Empty; + + using (var httpClient = new HttpClient()) + { + try + { + using (var reduceAttach = new MultipartFormDataContent()) + { + string[] allKeys = nameValueCollection.AllKeys; + foreach (string key in allKeys) + { + var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(nameValueCollection[key])); + + dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue($"form-data") + { + Name = key + }; + + reduceAttach.Add(dataContent); + } + + #region 文件参数 + if (fileInfo != null) + { + var Content = new ByteArrayContent(fileInfo.fileBytes); + + Content.Headers.Add("Content-Type", contentType); + + reduceAttach.Add(Content, fileInfo.file.ToString(), HttpUtility.UrlEncode(fileInfo.fileName.ToString())); + } + #endregion + + //请求 + var response = httpClient.PostAsync(requestUrl, reduceAttach).Result; + result = response.Content.ReadAsStringAsync().Result; + } + } + catch (Exception ex) + { + result = JSON.Serialize(new + { + message = $"{nameof(TransmitFile)} 请求打印生成文件异常,原因:{ex.Message}", + status = 0 + }); + } + + } + return result; + } + #endregion + } +} diff --git a/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs b/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs index 750ba971..d7e2f14d 100644 --- a/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs +++ b/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs @@ -8,24 +8,32 @@ using Furion.RemoteRequest.Extensions; using Mapster; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Myshipping.Application.ConfigOption; using Myshipping.Application.Entity; +using Myshipping.Application.Enum; using Myshipping.Application.Helper; using Myshipping.Core; using Myshipping.Core.Entity; +using Myshipping.Core.Helper; using Myshipping.Core.Service; using MySqlX.XDevAPI.Common; using NetTaste; using Newtonsoft.Json.Linq; +using NPOI.HSSF.UserModel; using NPOI.OpenXmlFormats.Wordprocessing; using NPOI.SS.Formula.Functions; using Org.BouncyCastle.Crypto; +using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; +using System.ComponentModel; +using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Web; namespace Myshipping.Application { @@ -44,6 +52,7 @@ namespace Myshipping.Application private readonly SqlSugarRepository _bookingCtnRepository; private readonly SqlSugarRepository _bookingPrintTemplateTemplate; private readonly SqlSugarRepository _djyUserConfigConfig; + private readonly SqlSugarRepository _bookingExcelTemplateRepository; private readonly ITaskManageExternalService _taskManageExternalService; const string PRINT_LIST_TYPE_KEY = "booking_truck_print_list"; @@ -55,7 +64,8 @@ namespace Myshipping.Application SqlSugarRepository bookingCtnRepository, SqlSugarRepository bookingPrintTemplateTemplate, SqlSugarRepository djyUserConfigConfig, - ITaskManageExternalService taskManageExternalService) + SqlSugarRepository bookingExcelTemplateRepository, + ITaskManageExternalService taskManageExternalService) { _cache = cache; _logger = logger; @@ -68,6 +78,7 @@ namespace Myshipping.Application _taskManageExternalService = taskManageExternalService; _bookingPrintTemplateTemplate = bookingPrintTemplateTemplate; _djyUserConfigConfig = djyUserConfigConfig; + _bookingExcelTemplateRepository = bookingExcelTemplateRepository; } /// @@ -1134,19 +1145,371 @@ namespace Myshipping.Application /// 派车主键 /// 打印模板ID /// 分类代码(使用字典【booking_template_category】中的代码) - /// 类型,1:pdf、2:xlsx、3:docx + /// 类型,1:pdf、2:xlsx、3:docx /// 打印类型,10:FastReport、20:Excel模板 /// 返回回执 [HttpGet("/BookingTruck/Print")] - public async Task Print(long id, long templateId, string cateCode, int type = 1, - BookingPrintTemplateType printType = BookingPrintTemplateType.FastReport) + public async Task Print([FromQuery]long id, [FromQuery] long templateId, [FromQuery] string cateCode, [FromQuery] PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF, + [FromQuery] BookingPrintTemplateType printType = BookingPrintTemplateType.FastReport) { + var printTemplate = await _bookingPrintTemplateTemplate.AsQueryable().Filter(null, true) + .FirstAsync(x => x.Id == templateId); + + if (printTemplate == null) + { + throw Oops.Bah(BookingErrorCode.BOOK115); + } + + //var order = await _bookingTruckRepository.FirstOrDefaultAsync(x => x.Id == bookingId); + //var edi = await _bookingEDIExt.FirstOrDefaultAsync(x => x.BookingId == bookingId); + //if (order == null) + //{ + // throw Oops.Bah(BookingErrorCode.BOOK001); + //} + + var fileName = string.Empty; + //var dicCate = (await _cache.GetAllDictData()).FirstOrDefault(x => x.Code == cateCode && x.TypeCode == "booking_template_category"); + //if (dicCate == null) + //{ + // throw Oops.Bah("分类代码参数不正确"); + //} + if (printType == BookingPrintTemplateType.FastReport) + { + #region FastReport打印 + var bs = await GenPrintFile(id, printTemplate, printFileType); + var fileType = ""; + if (printFileType == PrintFileTypeEnum.PDF) + { + fileType = ".pdf"; + } + else if (printFileType == PrintFileTypeEnum.XLSX) + { + fileType = ".xlsx"; + } + else if (printFileType == PrintFileTypeEnum.DOCX) + { + fileType = ".docx"; + } + else + { + throw Oops.Bah("类型参数不正确"); + } + + fileName = $"{DateTime.Now.Ticks}{fileType}";//名称 + + ////2023-4-3,根据河川操作要求,文件名只带提单号 + //if (!string.IsNullOrEmpty(order.MBLNO)) + //{ + // fileName = $"{order.MBLNO}{fileType}";//名称 + //} + //else + //{ + // fileName = $"{order.Id}_{DateTime.Now.Ticks}{fileType}";//名称 + //} + var opt = App.GetOptions().Path; + var serverpath = Path.Combine(App.WebHostEnvironment.WebRootPath, opt);//服务器路径 + if (!Directory.Exists(serverpath)) + { + Directory.CreateDirectory(serverpath); + } + + var fullPath = Path.Combine(serverpath, fileName); + await File.WriteAllBytesAsync(fullPath, bs); - return string.Empty; + #endregion + } + + /* + else if (printType == BookingPrintTemplateType.ExcelTemplate) + { + #region Excel模板打印 + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath); + _logger.LogInformation($"准备调用EXCEL生成:id:{id},文件:{printTemplate.FileName}"); + var result = new FileStream(fileAbsPath, FileMode.Open); + var excelwork = new HSSFWorkbook(result); + var sheet = excelwork.GetSheetAt(0); + var entity = await _bookingExcelTemplateRepository.AsQueryable() + .Where(x => x.PId == templateId).OrderBy(x => x.Row).ToListAsync(); + if (entity == null) + { + + throw Oops.Bah("当前模板未设置"); + + } + for (int _row = 1; _row <= entity.Max(x => x.Row); _row++) + { + + if (entity.Where(x => x.Row == _row).Count() > 0) + { + ////获取行 + var row = sheet.GetRow(_row - 1); + if (row != null) + { + for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) + { + if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) + { + var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); + + if (name.Split('.')[0].ToLower() == "order") + { + + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[0].ToLower() == "order" && name.Split('.')[1].ToLower() == _name) + { + var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; + ICell cell = row.GetCell(_cellNum - 1); + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + if (cell != null) + { + row.Cells[_cellNum - 1].SetCellValue(value); + } + else + { + row.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + + + } + + if (name.Split('.')[0].ToLower() == "edi") + { + + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[0].ToLower() == "edi" && name.Split('.')[1].ToLower() == _name) + { + var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; + ICell cell = row.GetCell(_cellNum - 1); + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + if (cell != null) + { + row.Cells[_cellNum - 1].SetCellValue(value); + } + else + { + row.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + + + } + + if (name.Split('.')[0].ToLower() == "userinfo") + { + ICell cell = row.GetCell(_cellNum - 1); + var value = string.Empty; + if (name.Split('.')[1].ToLower() == "username") + { + value = UserManager.Name; + } + if (name.Split('.')[1].ToLower() == "usertel") + { + value = UserManager.TEl; + } + if (name.Split('.')[1].ToLower() == "usermobile") + { + value = UserManager.Phone; + } + if (name.Split('.')[1].ToLower() == "useremail") + { + value = UserManager.Email; + } + if (name.Split('.')[1].ToLower() == "usertenant") + { + value = UserManager.TENANT_NAME; + } + if (cell != null) + { + row.Cells[_cellNum - 1].SetCellValue(value); + } + else + { + row.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + } + } + else + { + ////创建行 + var srow = NpoiExcelExportHelper._.CreateRow(sheet, _row - 1); + + for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) + { + if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) + { + var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); + + if (name.Split('.')[0].ToLower() == "order") + { + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "order") + { + var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + srow.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + if (name.Split('.')[0].ToLower() == "edi") + { + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "edi") + { + var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + srow.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + + if (name.Split('.')[0].ToLower() == "userinfo") + { + + var value = string.Empty; + if (name.Split('.')[1].ToLower() == "username") + { + value = UserManager.Name; + } + if (name.Split('.')[1].ToLower() == "usertel") + { + value = UserManager.TEl; + } + if (name.Split('.')[1].ToLower() == "usermobile") + { + value = UserManager.Phone; + } + if (name.Split('.')[1].ToLower() == "useremail") + { + value = UserManager.Email; + } + if (name.Split('.')[1].ToLower() == "usertenant") + { + value = UserManager.TENANT_NAME; + } + + srow.CreateCell(_cellNum - 1).SetCellValue(value); + + } + } + } + } + + } + } + var fileFullPath = Path.Combine(App.WebHostEnvironment.WebRootPath, App.GetOptions().Path);//服务器路径 + if (!Directory.Exists(fileFullPath)) + { + Directory.CreateDirectory(fileFullPath); + } + + fileName = $"{DateTime.Now.Ticks}.xls";//名称 + ////2023-4-3,根据河川操作要求,文件名只带提单号 + //if (!string.IsNullOrEmpty(order.MBLNO)) + //{ + // fileName = $"{order.MBLNO}.xls";//名称 + //} + //else + //{ + // fileName = $"{order.Id}_{DateTime.Now.Ticks}.xls";//名称 + //} + _logger.LogInformation("导出excel:" + Path.Combine(fileFullPath, fileName)); + var filestream = new FileStream(Path.Combine(fileFullPath, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite); + excelwork.Write(filestream); + + #endregion + } + */ + + //记录打印次数和时间,用于前端动态展示常用的打印类型 + var printRecentListKey = $"{PRINT_LIST_TYPE_KEY}_{cateCode}_{printType}"; + var usrCfg = _djyUserConfigConfig.AsQueryable().First(x => x.CreatedUserId == UserManager.UserId && x.Type == printRecentListKey); + if (usrCfg == null) + { + usrCfg = new DjyUserConfig(); + usrCfg.Type = printRecentListKey; + usrCfg.ConfigJson = (new long[] { templateId }).ToJson(); + await _djyUserConfigConfig.InsertAsync(usrCfg); + } + else + { + var arr = JArray.Parse(usrCfg.ConfigJson).Select(x => Convert.ToInt64(x)).Where(x => x != templateId).ToList(); + arr.Insert(0, templateId); + usrCfg.ConfigJson = arr.ToArray().ToJson(); + await _djyUserConfigConfig.UpdateAsync(usrCfg); + } + + return HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8")); + } + + /// + /// 生成打印报表文件 + /// + /// 派车ID + /// 打印模板 + /// 文档类型,1:pdf、2:xlsx、3:docx + /// 返回文件流 + [NonAction] + private async Task GenPrintFile(long bookingTruckId, BookingPrintTemplate printTemplate, + PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF) + { + //打印报表服务地址 + var reportUrl = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_set" + && x.Code == "url_report_generate").Value; + + if (!reportUrl.EndsWith("/")) + { + reportUrl += "/"; + } + + var genUrl = $"{reportUrl}PrintReport"; + + var truckOrder = _bookingTruckRepository.AsQueryable().First(a => a.Id == bookingTruckId); + + if (truckOrder == null) + throw Oops.Oh($"派车主键{bookingTruckId}无法获取业务信息"); + + var truckCtnList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == bookingTruckId).ToList(); + + BookingTruckShowDto model = truckOrder.Adapt(); + + if (truckCtnList.Count > 0) + model.ContaList = truckCtnList.Adapt>(); + + return await PrintHelper.GeneratePrintFile(JSON.Serialize(model), genUrl, printFileType, printTemplate); } - #region 校验派车 /// diff --git a/Myshipping.Application/Service/BookingTruck/Interface/IBookingTruckService.cs b/Myshipping.Application/Service/BookingTruck/Interface/IBookingTruckService.cs index 94c69900..77c21008 100644 --- a/Myshipping.Application/Service/BookingTruck/Interface/IBookingTruckService.cs +++ b/Myshipping.Application/Service/BookingTruck/Interface/IBookingTruckService.cs @@ -1,4 +1,5 @@ -using Myshipping.Core; +using Microsoft.AspNetCore.Mvc; +using Myshipping.Core; using System; using System.Collections.Generic; using System.Linq; @@ -110,12 +111,22 @@ namespace Myshipping.Application /// 派车主键 /// 打印模板ID /// 分类代码(使用字典【booking_template_category】中的代码) - /// 类型,1:pdf、2:xlsx、3:docx + /// 类型,1:pdf、2:xlsx、3:docx /// 打印类型,10:FastReport、20:Excel模板 /// 返回回执 - Task Print(long id, long templateId, string cateCode, int type = 1, + Task Print(long id, long templateId, string cateCode, PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF, BookingPrintTemplateType printType = BookingPrintTemplateType.FastReport); - + + /// + /// 获取订舱打印模板列表(带有当前用户打印历史排序) + /// + /// 分类代码(使用字典【booking_template_category】中的代码) + /// 打印分类,10:FastReport、20:Excel模板 + /// + Task PrintTemplateWithHistoryList(string cateCode, BookingPrintTemplateType printType); + + + } } diff --git a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageTruckService.cs b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageTruckService.cs index 40404d1a..48f32a4c 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageTruckService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageTruckService.cs @@ -32,13 +32,6 @@ namespace Myshipping.Application /// 返回回执 Task GetInfoByTaskId(string taskPkId); - /// - /// 打印派车 - /// - /// 派车主键 - /// 返回回执 - Task Print(string pkId); - /// /// 批量派车 /// @@ -59,5 +52,25 @@ namespace Myshipping.Application /// 派车主键组 /// 返回回执 Task CancelDispatchBatch(string[] pkIds); + + /// + /// 打印派车 + /// + /// 派车主键 + /// 打印模板ID + /// 分类代码(使用字典【booking_template_category】中的代码) + /// 类型,1:pdf、2:xlsx、3:docx + /// 打印类型,10:FastReport、20:Excel模板 + /// 返回回执 + Task Print(string taskPKId, long templateId, string cateCode, PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF, + BookingPrintTemplateType printType = BookingPrintTemplateType.FastReport); + + /// + /// 获取订舱打印模板列表(带有当前用户打印历史排序) + /// + /// 分类代码(使用字典【booking_template_category】中的代码) + /// 打印分类,10:FastReport、20:Excel模板 + /// + Task PrintTemplateWithHistoryList(string cateCode, BookingPrintTemplateType printType); } } diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageTruckService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageTruckService.cs index 8e111bc4..c2a8336b 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageTruckService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageTruckService.cs @@ -1,17 +1,25 @@ -using Furion.DistributedIDGenerator; +using Furion; +using Furion.DistributedIDGenerator; using Furion.DynamicApiController; using Furion.FriendlyException; +using Furion.JsonSerialization; using Mapster; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Myshipping.Application.Entity; +using Myshipping.Application.Enum; using Myshipping.Core; +using Myshipping.Core.Entity; using Myshipping.Core.Service; +using Newtonsoft.Json.Linq; +using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; namespace Myshipping.Application { @@ -27,10 +35,18 @@ namespace Myshipping.Application private readonly SqlSugarRepository _taskTruckRepository; private readonly SqlSugarRepository _taskTruckContaRepository; private readonly SqlSugarRepository _taskBaseRepository; + private readonly SqlSugarRepository _bookingPrintTemplateTemplate; + private readonly SqlSugarRepository _djyUserConfigConfig; + private readonly SqlSugarRepository _bookingExcelTemplateRepository; + + const string PRINT_LIST_TYPE_KEY = "booking_truck_print_list"; public TaskManageTruckService(SqlSugarRepository taskTruckRepository, SqlSugarRepository taskTruckContaRepository, SqlSugarRepository taskBaseRepository, + SqlSugarRepository bookingPrintTemplateTemplate, + SqlSugarRepository djyUserConfigConfig, + SqlSugarRepository bookingExcelTemplateRepository, ISysCacheService cache, ILogger logger) { _cache = cache; @@ -39,6 +55,10 @@ namespace Myshipping.Application _taskTruckRepository = taskTruckRepository; _taskTruckContaRepository = taskTruckContaRepository; _taskBaseRepository = taskBaseRepository; + + _bookingPrintTemplateTemplate = bookingPrintTemplateTemplate; + _djyUserConfigConfig = djyUserConfigConfig; + _bookingExcelTemplateRepository = bookingExcelTemplateRepository; } /// @@ -248,23 +268,372 @@ namespace Myshipping.Application /// /// 打印派车 /// - /// 派车主键 + /// 派车主键 + /// 打印模板ID + /// 分类代码(使用字典【booking_template_category】中的代码) + /// 类型,1:pdf、2:xlsx、3:docx + /// 打印类型,10:FastReport、20:Excel模板 /// 返回回执 [HttpGet("/TaskManageTruck/Print")] - public async Task Print(string pkId) + public async Task Print([FromQuery] string taskPKId, [FromQuery] long templateId, [FromQuery] string cateCode, [FromQuery] PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF, + [FromQuery] BookingPrintTemplateType printType = BookingPrintTemplateType.FastReport) { - TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + var printTemplate = await _bookingPrintTemplateTemplate.AsQueryable().Filter(null, true) + .FirstAsync(x => x.Id == templateId); - try + if (printTemplate == null) { + throw Oops.Bah(BookingErrorCode.BOOK115); + } + + //var order = await _bookingTruckRepository.FirstOrDefaultAsync(x => x.Id == bookingId); + //var edi = await _bookingEDIExt.FirstOrDefaultAsync(x => x.BookingId == bookingId); + //if (order == null) + //{ + // throw Oops.Bah(BookingErrorCode.BOOK001); + //} + + var fileName = string.Empty; + //var dicCate = (await _cache.GetAllDictData()).FirstOrDefault(x => x.Code == cateCode && x.TypeCode == "booking_template_category"); + //if (dicCate == null) + //{ + // throw Oops.Bah("分类代码参数不正确"); + //} + + if (printType == BookingPrintTemplateType.FastReport) + { + #region FastReport打印 + var bs = await GenPrintFile(taskPKId, printTemplate, printFileType); + var fileType = ""; + if (printFileType == PrintFileTypeEnum.PDF) + { + fileType = ".pdf"; + } + else if (printFileType == PrintFileTypeEnum.XLSX) + { + fileType = ".xlsx"; + } + else if (printFileType == PrintFileTypeEnum.DOCX) + { + fileType = ".docx"; + } + else + { + throw Oops.Bah("类型参数不正确"); + } + + fileName = $"{DateTime.Now.Ticks}{fileType}";//名称 + + ////2023-4-3,根据河川操作要求,文件名只带提单号 + //if (!string.IsNullOrEmpty(order.MBLNO)) + //{ + // fileName = $"{order.MBLNO}{fileType}";//名称 + //} + //else + //{ + // fileName = $"{order.Id}_{DateTime.Now.Ticks}{fileType}";//名称 + //} + var opt = App.GetOptions().Path; + var serverpath = Path.Combine(App.WebHostEnvironment.WebRootPath, opt);//服务器路径 + if (!Directory.Exists(serverpath)) + { + Directory.CreateDirectory(serverpath); + } + var fullPath = Path.Combine(serverpath, fileName); + await File.WriteAllBytesAsync(fullPath, bs); + + #endregion } - catch (Exception ex) + + /* + else if (printType == BookingPrintTemplateType.ExcelTemplate) { + #region Excel模板打印 + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath); + _logger.LogInformation($"准备调用EXCEL生成:id:{id},文件:{printTemplate.FileName}"); + var result = new FileStream(fileAbsPath, FileMode.Open); + var excelwork = new HSSFWorkbook(result); + var sheet = excelwork.GetSheetAt(0); + var entity = await _bookingExcelTemplateRepository.AsQueryable() + .Where(x => x.PId == templateId).OrderBy(x => x.Row).ToListAsync(); + if (entity == null) + { + + throw Oops.Bah("当前模板未设置"); + + } + for (int _row = 1; _row <= entity.Max(x => x.Row); _row++) + { + if (entity.Where(x => x.Row == _row).Count() > 0) + { + ////获取行 + var row = sheet.GetRow(_row - 1); + if (row != null) + { + for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) + { + if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) + { + var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); + + if (name.Split('.')[0].ToLower() == "order") + { + + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[0].ToLower() == "order" && name.Split('.')[1].ToLower() == _name) + { + var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; + ICell cell = row.GetCell(_cellNum - 1); + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + if (cell != null) + { + row.Cells[_cellNum - 1].SetCellValue(value); + } + else + { + row.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + + + } + + if (name.Split('.')[0].ToLower() == "edi") + { + + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[0].ToLower() == "edi" && name.Split('.')[1].ToLower() == _name) + { + var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; + ICell cell = row.GetCell(_cellNum - 1); + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + if (cell != null) + { + row.Cells[_cellNum - 1].SetCellValue(value); + } + else + { + row.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + + + } + + if (name.Split('.')[0].ToLower() == "userinfo") + { + ICell cell = row.GetCell(_cellNum - 1); + var value = string.Empty; + if (name.Split('.')[1].ToLower() == "username") + { + value = UserManager.Name; + } + if (name.Split('.')[1].ToLower() == "usertel") + { + value = UserManager.TEl; + } + if (name.Split('.')[1].ToLower() == "usermobile") + { + value = UserManager.Phone; + } + if (name.Split('.')[1].ToLower() == "useremail") + { + value = UserManager.Email; + } + if (name.Split('.')[1].ToLower() == "usertenant") + { + value = UserManager.TENANT_NAME; + } + if (cell != null) + { + row.Cells[_cellNum - 1].SetCellValue(value); + } + else + { + row.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + } + } + else + { + ////创建行 + var srow = NpoiExcelExportHelper._.CreateRow(sheet, _row - 1); + + for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) + { + if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) + { + var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); + + if (name.Split('.')[0].ToLower() == "order") + { + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "order") + { + var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + srow.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + if (name.Split('.')[0].ToLower() == "edi") + { + foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) + { + var _name = descriptor.Name.ToLower(); + if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "edi") + { + var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; + if (descriptor.PropertyType.FullName.Contains("DateTime")) + { + value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + } + srow.CreateCell(_cellNum - 1).SetCellValue(value); + } + } + } + + if (name.Split('.')[0].ToLower() == "userinfo") + { + + var value = string.Empty; + if (name.Split('.')[1].ToLower() == "username") + { + value = UserManager.Name; + } + if (name.Split('.')[1].ToLower() == "usertel") + { + value = UserManager.TEl; + } + if (name.Split('.')[1].ToLower() == "usermobile") + { + value = UserManager.Phone; + } + if (name.Split('.')[1].ToLower() == "useremail") + { + value = UserManager.Email; + } + if (name.Split('.')[1].ToLower() == "usertenant") + { + value = UserManager.TENANT_NAME; + } + + srow.CreateCell(_cellNum - 1).SetCellValue(value); + + } + } + } + } + + } + } + var fileFullPath = Path.Combine(App.WebHostEnvironment.WebRootPath, App.GetOptions().Path);//服务器路径 + if (!Directory.Exists(fileFullPath)) + { + Directory.CreateDirectory(fileFullPath); + } + + fileName = $"{DateTime.Now.Ticks}.xls";//名称 + ////2023-4-3,根据河川操作要求,文件名只带提单号 + //if (!string.IsNullOrEmpty(order.MBLNO)) + //{ + // fileName = $"{order.MBLNO}.xls";//名称 + //} + //else + //{ + // fileName = $"{order.Id}_{DateTime.Now.Ticks}.xls";//名称 + //} + _logger.LogInformation("导出excel:" + Path.Combine(fileFullPath, fileName)); + var filestream = new FileStream(Path.Combine(fileFullPath, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite); + excelwork.Write(filestream); + + #endregion } + */ - return result; + //记录打印次数和时间,用于前端动态展示常用的打印类型 + var printRecentListKey = $"{PRINT_LIST_TYPE_KEY}_{cateCode}_{printType}"; + var usrCfg = _djyUserConfigConfig.AsQueryable().First(x => x.CreatedUserId == UserManager.UserId && x.Type == printRecentListKey); + if (usrCfg == null) + { + usrCfg = new DjyUserConfig(); + usrCfg.Type = printRecentListKey; + usrCfg.ConfigJson = (new long[] { templateId }).ToJson(); + await _djyUserConfigConfig.InsertAsync(usrCfg); + } + else + { + var arr = JArray.Parse(usrCfg.ConfigJson).Select(x => Convert.ToInt64(x)).Where(x => x != templateId).ToList(); + arr.Insert(0, templateId); + usrCfg.ConfigJson = arr.ToArray().ToJson(); + await _djyUserConfigConfig.UpdateAsync(usrCfg); + } + + return HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8")); + } + + /// + /// 生成打印报表文件 + /// + /// 派车ID + /// 打印模板 + /// 文档类型,1:pdf、2:xlsx、3:docx + /// 返回文件流 + [NonAction] + private async Task GenPrintFile(string taskTruckId, BookingPrintTemplate printTemplate, + PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF) + { + //打印报表服务地址 + var reportUrl = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_set" + && x.Code == "url_report_generate").Value; + + if (!reportUrl.EndsWith("/")) + { + reportUrl += "/"; + } + + var genUrl = $"{reportUrl}PrintReport"; + + var truckOrder = _taskTruckRepository.AsQueryable().First(a => a.PK_ID == taskTruckId); + + if (truckOrder == null) + throw Oops.Oh($"派车主键{taskTruckId}无法获取业务信息"); + + var truckCtnList = _taskTruckContaRepository.AsQueryable().Where(a => a.P_ID == taskTruckId).ToList(); + + BookingTruckShowDto model = truckOrder.Adapt(); + + if (truckCtnList.Count > 0) + model.ContaList = truckCtnList.Adapt>(); + + return await PrintHelper.GeneratePrintFile(JSON.Serialize(model), genUrl, printFileType, printTemplate); } /// @@ -374,5 +743,59 @@ namespace Myshipping.Application } } #endregion + + /// + /// 获取订舱打印模板列表(带有当前用户打印历史排序) + /// + /// 分类代码(使用字典【booking_template_category】中的代码) + /// 打印分类,10:FastReport、20:Excel模板 + /// + [HttpGet("/TaskManageTruck/PrintTemplateWithHistoryList")] + public async Task PrintTemplateWithHistoryList(string cateCode, BookingPrintTemplateType printType) + { + var typeCode = printType.ToString(); + //当前公司所有已配置的模板 + var allList = await _bookingPrintTemplateTemplate.AsQueryable() + .Filter(null, true).InnerJoin((d, t) => d.Id == t.PrintTemplateId && t.SysUserId == UserManager.UserId) + .Where(d => d.TenantId == UserManager.TENANT_ID && d.CateCode.Contains(cateCode) && d.Type == typeCode) + .Select(d => new + { + d.Id, + d.CateCode, + d.CateName, + d.DisplayName + + }) + .ToListAsync(); + + var listReult = new List(); + //当前用户打印历史数据 + var printRecentListKey = $"{PRINT_LIST_TYPE_KEY}_{cateCode}_{printType}"; + var usrCfg = await _djyUserConfigConfig.AsQueryable().FirstAsync(x => x.CreatedUserId == UserManager.UserId && x.Type == printRecentListKey); + if (usrCfg != null) + { + var arr = JArray.Parse(usrCfg.ConfigJson).Select(x => Convert.ToInt64(x)).ToList(); + + //按顺序加入到结果 + arr.ForEach(x => + { + var find = allList.FirstOrDefault(y => y.Id == x); + if (find != null) + { + listReult.Add(find); + } + }); + + var listOut = allList.Where(x => !arr.Contains(x.Id)).ToList(); + listReult.AddRange(listOut); + + return listReult; + } + else + { + return allList; + } + } + } }