| | |
| | | using static WIDESEA_Common.NewHouseInboundPassBack.Parame.Syncretism; |
| | | using static WIDESEA_ITaskInfoService.ITaskService; |
| | | using Parameter = WIDESEA_Common.Parameter; |
| | | using WIDESEA_DTO.ERP; |
| | | using WIDESEA_OutboundRepository; |
| | | using System.ComponentModel.DataAnnotations; |
| | | using System; |
| | | using System.IO; |
| | | using System.Net.Http; |
| | | using System.Threading.Tasks; |
| | | using Spire.Pdf; |
| | | using WIDESEA_InboundRepository; |
| | | using System.Drawing.Printing; |
| | | using System; |
| | | using WIDESEA_Common.Log; |
| | | using static WIDESEA_Common.HouseInboundPassBack.data.data1; |
| | | using System.Diagnostics; |
| | | |
| | | namespace WIDESEA_TaskInfoService |
| | | { |
| | |
| | | return WebResponseContent.Instance.Error($"未找到对应的入库单明细"); |
| | | } |
| | | |
| | | // 更新入库单明细状态 |
| | | // 更新入库单明细状态 |
| | | foreach (var inboundOrderDetail in inboundOrderDetails) |
| | | { |
| | | // 检查该明细是否已全部入库 |
| | |
| | | .ToList(); |
| | | |
| | | Dt_InboundOrder? dt_InboundOrder = _inboundService.InbounOrderService.Db.Queryable<Dt_InboundOrder>().Where(x => x.OrderNo == inboundOrder.OrderNo).Includes(x => x.Details).First(); |
| | | if (StockInfos.Count == 0) throw new Exception("未找到库存信息"); |
| | | if (StockInfos.Count == 0) throw new Exception("未找到库存信息"); |
| | | |
| | | var houseSyncretism = new NewHouseInboundPassBack |
| | | { |
| | |
| | | .Where(x => x.OrderId == outboundOrder.Id) |
| | | .ToList(); |
| | | } |
| | | if ((outboundOrderDetails == null && outboundOrderDetails1 == null) || (outboundOrderDetails.Count == 0 && outboundOrderDetails1.Count == 0)) |
| | | if ((outboundOrderDetails == null && outboundOrderDetails1 == null) || (outboundOrderDetails.Count == 0 && outboundOrderDetails1.Count == 0)) |
| | | { |
| | | throw new Exception($"未找到托盘 {stockInfo.PalletCode} 在货位 {stockInfo.LocationCode} 上的出库单明细"); |
| | | } |
| | |
| | | { |
| | | Dt_OutboundOrderDetail outboundOrderDetail = _outboundService.OutboundOrderService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .Where(x => x.OrderId == inboundOrder.Id && x.BatchNo == detail.BatchNo).First(); |
| | | outboundOrderDetails.Add(outboundOrderDetail); |
| | | if (outboundOrderDetail != null) |
| | | { |
| | | outboundOrderDetails.Add(outboundOrderDetail); |
| | | } |
| | | |
| | | } |
| | | |
| | | for (var i = 0; i<outboundOrderDetails.Count; i++) |
| | | for (var i = 0; i < outboundOrderDetails.Count; i++) |
| | | { |
| | | if (outboundOrderDetails[i].LocationName != null && outboundOrderDetails[i].LocationName != "") |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | public virtual void PrintTestDirect(string fullPath) |
| | | public void PrintTestDirect(string fullPath) |
| | | { |
| | | const int maxRetryCount = 3; |
| | | const int retryDelayMs = 1000; |
| | | |
| | | if (!File.Exists(fullPath)) |
| | | { |
| | | Console.WriteLine($"打印失败:文件不存在 {fullPath}"); |
| | | Console.WriteLine($"✗ 打印失败:文件不存在 {fullPath}"); |
| | | return; |
| | | } |
| | | |
| | | // 获取配置的打印机名称 |
| | | string printerName = AppSettings.app("PrinterName"); |
| | | // 获取打印机名称配置 |
| | | string printerName = AppSettings.app("PrinterName")?.Trim(); |
| | | |
| | | if (string.IsNullOrEmpty(printerName)) |
| | | { |
| | | Console.WriteLine("✗ 打印失败:未配置打印机名称"); |
| | | return; |
| | | // 如果没有配置,使用系统默认打印机 |
| | | printerName = GetDefaultPrinterUbuntu(); |
| | | } |
| | | |
| | | // 直接使用配置的打印机名称,不进行任何转换 |
| | | PrintUsingConfiguredPrinter(fullPath, printerName.Trim()); |
| | | PrintUsingUbuntuPrinter(fullPath, printerName); |
| | | } |
| | | /// <summary> |
| | | /// 获取 Ubuntu 默认打印机 |
| | | /// </summary> |
| | | private string GetDefaultPrinterUbuntu() |
| | | { |
| | | try |
| | | { |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | FileName = "lpstat", |
| | | Arguments = "-d", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | RedirectStandardOutput = true |
| | | }; |
| | | |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | process.Start(); |
| | | string output = process.StandardOutput.ReadToEnd(); |
| | | process.WaitForExit(); |
| | | |
| | | // 解析默认打印机名称,例如: "system default destination: LenovoPrinter" |
| | | if (output.Contains(":")) |
| | | { |
| | | return output.Split(':')[1].Trim(); |
| | | } |
| | | return "LenovoPrinter"; // 默认回退 |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | return "LenovoPrinter"; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Ubuntu 打印实现 |
| | | /// </summary> |
| | | private void PrintUsingUbuntuPrinter(string filePath, string printerName) |
| | | { |
| | | try |
| | | { |
| | | PrintWithLpr(filePath, printerName); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"✗ 打印失败: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 使用 lpr 命令打印 |
| | | /// </summary> |
| | | private void PrintWithLpr(string filePath, string printerName) |
| | | { |
| | | Console.WriteLine($"📄 正在打印到 {printerName}: {Path.GetFileName(filePath)}"); |
| | | |
| | | // 使用 lp 命令,添加 -o raw 选项 |
| | | string command = $"lp -d {printerName} -o raw \"{filePath}\""; |
| | | |
| | | ExecuteShellCommand(command); |
| | | } |
| | | /// <summary> |
| | | /// 执行 Shell 命令 |
| | | /// </summary> |
| | | private void ExecuteShellCommand(string command) |
| | | { |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | FileName = "/bin/bash", |
| | | Arguments = $"-c \"{command.Replace("\"", "\\\"")}\"", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | RedirectStandardOutput = true, |
| | | RedirectStandardError = true |
| | | }; |
| | | |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | process.Start(); |
| | | string output = process.StandardOutput.ReadToEnd(); |
| | | string error = process.StandardError.ReadToEnd(); |
| | | process.WaitForExit(); |
| | | |
| | | if (process.ExitCode == 0) |
| | | { |
| | | Console.WriteLine($"✅ 打印任务提交成功"); |
| | | if (!string.IsNullOrEmpty(output)) |
| | | Console.WriteLine($"输出: {output}"); |
| | | } |
| | | else |
| | | { |
| | | throw new InvalidOperationException($"命令执行失败: {error}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 只使用配置的打印机进行打印 |
| | | /// </summary> |
| | | /// <summary> |
| | | /// Ubuntu 打印方法 - 使用 lpr 命令 |
| | | /// </summary> |
| | | private void PrintUsingConfiguredPrinter(string filePath, string printerName) |
| | | { |
| | | try |
| | | { |
| | | // 1. 首先验证打印机是否存在 |
| | | if (!IsPrinterInstalled(printerName)) |
| | | // 1. 检查打印机是否在线 |
| | | if (!IsPrinterAvailableUbuntu(printerName)) |
| | | { |
| | | Console.WriteLine($"✗ 打印机 '{printerName}' 未安装或不存在"); |
| | | Console.WriteLine("\n系统已安装的打印机列表:"); |
| | | foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters) |
| | | { |
| | | Console.WriteLine($" - {printer}"); |
| | | } |
| | | throw new InvalidOperationException($"打印机 '{printerName}' 未安装"); |
| | | throw new InvalidOperationException($"打印机 '{printerName}' 不可用或未找到"); |
| | | } |
| | | |
| | | // 3. 使用 Spire.PDF 打印 |
| | | using (Spire.Pdf.PdfDocument pdf = new Spire.Pdf.PdfDocument()) |
| | | Console.WriteLine($"✓ 使用打印机: {printerName}"); |
| | | Console.WriteLine($"✓ 正在打印: {Path.GetFileName(filePath)}"); |
| | | |
| | | // 2. 使用 lpr 命令打印 |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | // 加载文件 |
| | | pdf.LoadFromFile(filePath); |
| | | FileName = "lpr", |
| | | Arguments = $"-P {printerName} \"{filePath}\"", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | RedirectStandardOutput = true, |
| | | RedirectStandardError = true |
| | | }; |
| | | |
| | | // 设置打印机名称(只使用配置的名称) |
| | | pdf.PrintSettings.PrinterName = printerName; |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | process.Start(); |
| | | string output = process.StandardOutput.ReadToEnd(); |
| | | string error = process.StandardError.ReadToEnd(); |
| | | process.WaitForExit(); |
| | | |
| | | Console.WriteLine($"✓ 使用配置的打印机: {printerName}"); |
| | | Console.WriteLine($"✓ 正在打印: {Path.GetFileName(filePath)}"); |
| | | |
| | | // 直接打印 |
| | | pdf.Print(); |
| | | Console.WriteLine("✓ 打印任务已提交"); |
| | | if (process.ExitCode == 0) |
| | | { |
| | | Console.WriteLine($"✓ 打印任务已提交到 {printerName}"); |
| | | } |
| | | else |
| | | { |
| | | throw new InvalidOperationException($"打印失败: {error}"); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 从配置的友好名称获取实际的打印机名称 |
| | | /// Ubuntu 检查打印机可用性 |
| | | /// </summary> |
| | | private string GetActualPrinterName(string displayName) |
| | | { |
| | | if (string.IsNullOrEmpty(displayName)) |
| | | return string.Empty; |
| | | |
| | | // 如果配置的是 "192.168.99.3 上的 Lenovo M7605D" |
| | | if (displayName.Contains("192.168.99.3 上的 Lenovo M7605D")) |
| | | { |
| | | // 在系统中查找实际的打印机名称 |
| | | return FindActualPrinterForIP("192.168.99.3"); |
| | | } |
| | | |
| | | // 如果直接配置的是IP地址 |
| | | if (displayName.Contains("192.168.99.3")) |
| | | { |
| | | return FindActualPrinterForIP("192.168.99.3"); |
| | | } |
| | | |
| | | // 如果已经是实际的打印机名称,直接返回 |
| | | if (IsPrinterInstalled(displayName)) |
| | | { |
| | | return displayName; |
| | | } |
| | | |
| | | // 默认返回原名称 |
| | | return displayName; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查找IP地址对应的实际打印机名称 |
| | | /// </summary> |
| | | private string FindActualPrinterForIP(string ipAddress) |
| | | private bool IsPrinterAvailableUbuntu(string printerName) |
| | | { |
| | | try |
| | | { |
| | | // 获取所有打印机 |
| | | var allPrinters = new List<string>(); |
| | | foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters) |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | allPrinters.Add(printer); |
| | | } |
| | | |
| | | Console.WriteLine($"查找IP地址 {ipAddress} 对应的打印机..."); |
| | | Console.WriteLine("系统打印机列表:"); |
| | | foreach (var printer in allPrinters) |
| | | { |
| | | Console.WriteLine($" - {printer}"); |
| | | } |
| | | |
| | | // 优先查找包含IP地址的打印机 |
| | | foreach (string printer in allPrinters) |
| | | { |
| | | if (printer.Contains(ipAddress)) |
| | | { |
| | | Console.WriteLine($"✓ 找到包含IP的打印机: {printer}"); |
| | | return printer; |
| | | } |
| | | } |
| | | |
| | | // 查找联想打印机 |
| | | foreach (string printer in allPrinters) |
| | | { |
| | | if (printer.Contains("M7605D", StringComparison.OrdinalIgnoreCase)) |
| | | { |
| | | Console.WriteLine($"✓ 找到联想打印机: {printer}"); |
| | | return printer; |
| | | } |
| | | } |
| | | |
| | | |
| | | // 返回第一个可用的打印机 |
| | | if (allPrinters.Any()) |
| | | { |
| | | Console.WriteLine($"⚠️ 未找到精确匹配,使用第一个打印机: {allPrinters.First()}"); |
| | | return allPrinters.First(); |
| | | } |
| | | |
| | | return string.Empty; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"查找打印机失败: {ex.Message}"); |
| | | return string.Empty; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 检查打印机是否已安装 |
| | | /// </summary> |
| | | private bool IsPrinterInstalled(string printerName) |
| | | { |
| | | try |
| | | { |
| | | foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters) |
| | | { |
| | | if (printer.Equals(printerName, StringComparison.OrdinalIgnoreCase)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | catch |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 使用原始打印命令 |
| | | /// </summary> |
| | | private void PrintUsingRawCommand(string filePath, string printerName) |
| | | { |
| | | try |
| | | { |
| | | var processStartInfo = new System.Diagnostics.ProcessStartInfo |
| | | { |
| | | FileName = filePath, |
| | | Verb = "print", // 使用"print"动词 |
| | | UseShellExecute = true, // 关键:启用Shell执行 |
| | | FileName = "lpstat", |
| | | Arguments = $"-p {printerName}", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden |
| | | RedirectStandardOutput = true |
| | | }; |
| | | |
| | | // 设置打印机(可选,系统通常会使用默认打印机) |
| | | // processStartInfo.Arguments = $"/t \"{filePath}\" \"{printerName}\""; |
| | | |
| | | System.Diagnostics.Process.Start(processStartInfo); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"打印失败: {ex.Message}"); |
| | | // 可以尝试其他方法 |
| | | //TryAlternativePrintMethod(filePath, printerName); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 检查文件是否可访问 |
| | | /// </summary> |
| | | private bool IsFileAccessible(string filePath) |
| | | { |
| | | try |
| | | { |
| | | using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | return fs.Length > 0; |
| | | process.Start(); |
| | | string output = process.StandardOutput.ReadToEnd(); |
| | | process.WaitForExit(); |
| | | |
| | | return output.Contains($"{printerName} is idle") || |
| | | output.Contains($"{printerName} is ready"); |
| | | } |
| | | } |
| | | catch |
| | |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 尝试强制垃圾回收,释放可能存在的文件句柄 |
| | | /// </summary> |
| | | private void TryForceGarbageCollection() |
| | | { |
| | | try |
| | | { |
| | | GC.Collect(); |
| | | GC.WaitForPendingFinalizers(); |
| | | Console.WriteLine("已执行垃圾回收"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"垃圾回收失败: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 盘点出库完成 |
| | | /// </summary> |