| | |
| | | using System; |
| | | using WIDESEA_Common.Log; |
| | | using static WIDESEA_Common.HouseInboundPassBack.data.data1; |
| | | using System.Diagnostics; |
| | | |
| | | namespace WIDESEA_TaskInfoService |
| | | { |
| | |
| | | return WebResponseContent.Instance.Error("未找到入库单信息"); |
| | | } |
| | | var allBoxCodesForDetail = BaseDal.Db.Queryable<Dt_StockInfoDetailCP>() |
| | | .Where(x => x.StockDetailId == dt_StockInfo.Details.FirstOrDefault().Id) |
| | | .Select(x => x.BoxCode) |
| | | .ToList(); |
| | | .Where(x => dt_StockInfo.Details.Select(d => d.Id).Contains(x.StockDetailId)) |
| | | .Select(x => x.BoxCode) |
| | | .ToList(); |
| | | |
| | | // 2. 获取托盘下的所有箱号 |
| | | var boxCodes = new List<string>(); |
| | |
| | | .ToList(); |
| | | } |
| | | |
| | | // 更新成品入库明细状态 |
| | | if (cpInboundDetails.Any()) |
| | | { |
| | | foreach (var cpDetail in cpInboundDetails) |
| | | { |
| | | cpDetail.CPOrderDetailStatus = InboundStatusEnum.入库完成.ObjToInt(); |
| | | } |
| | | } |
| | | |
| | | // 4. 查询并更新成品库存明细(如果有单独的成品库存表) |
| | | List<Dt_StockInfoDetailCP> cpStockDetails = new List<Dt_StockInfoDetailCP>(); |
| | |
| | | // 更新成品入库明细状态 |
| | | if (cpInboundDetails.Any()) |
| | | { |
| | | BaseDal.Db.Updateable(cpInboundDetails).ExecuteCommand(); |
| | | BaseDal.Db.Deleteable(cpInboundDetails).ExecuteCommand(); |
| | | } |
| | | |
| | | // 更新成品库存明细状态 |
| | |
| | | } |
| | | if (inboundOrder.OrderStatus == InboundStatusEnum.入库完成.ObjToInt() && inboundOrder.OrderType == 0 && inboundOrder.System.Equals("SMOM")) |
| | | { |
| | | |
| | | //SendInboundInfoToWMS(task, inboundOrder, stockInfo); |
| | | } |
| | | else if (inboundOrder.OrderStatus == InboundStatusEnum.入库完成.ObjToInt() && inboundOrder.OrderType == 2 && inboundOrder.System.Equals("SMOM")) |
| | | { |
| | |
| | | |
| | | if (inboundOrder == null) return WebResponseContent.Instance.Error("未找到出库单信息"); |
| | | |
| | | Dt_OutboundOrderDetail outboundOrderDetail = new Dt_OutboundOrderDetail(); |
| | | foreach (var detail in stockInfo.Details) |
| | | List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>(); |
| | | foreach(var detail in stockInfo.Details) |
| | | { |
| | | outboundOrderDetail = _outboundService.OutboundOrderService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .Where(x => x.OrderId == inboundOrder.Id && x.BatchNo == detail.BatchNo) |
| | | .First(); |
| | | if (outboundOrderDetail != null) break; |
| | | |
| | | 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.LocationName != null && outboundOrderDetail.LocationName != "") |
| | | for(var i = 0; i<outboundOrderDetails.Count; i++) |
| | | { |
| | | foreach (var detail in stockInfo.Details) |
| | | if (outboundOrderDetails[i].LocationName != null && outboundOrderDetails[i].LocationName != "") |
| | | { |
| | | outboundOrderDetail = _outboundService.OutboundOrderService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .Where(x => x.OrderId == inboundOrder.Id && x.BatchNo == detail.BatchNo && x.LocationName == stockInfo.LocationCode) |
| | | .First(); |
| | | if (outboundOrderDetail != null) break; |
| | | foreach (var detail in stockInfo.Details) |
| | | { |
| | | Dt_OutboundOrderDetail newOutboundOrderDetail = _outboundService.OutboundOrderService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .Where(x => x.OrderId == inboundOrder.Id && x.BatchNo == detail.BatchNo && x.LocationName == stockInfo.LocationCode) |
| | | .First(); |
| | | outboundOrderDetails[i] = newOutboundOrderDetail; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (outboundOrderDetail == null) return WebResponseContent.Instance.Error("未找到出库单信息"); |
| | | DWANDYSUpdateOutboundOrderDetails(stockInfo, inboundOrder, ref outboundOrderDetail); |
| | | if (outboundOrderDetails == null) return WebResponseContent.Instance.Error("未找到出库单信息"); |
| | | DWANDYSUpdateOutboundOrderDetails(stockInfo, inboundOrder, ref outboundOrderDetails); |
| | | // 3. 执行核心出库逻辑 |
| | | return ExecuteOutboundLogic(task, stockInfo, locationInfo, outboundOrderDetail, inboundOrder); |
| | | return DWANDYSExecuteOutboundLogic(task, stockInfo, locationInfo, outboundOrderDetails, inboundOrder); |
| | | } |
| | | else |
| | | { |
| | |
| | | _outboundService.OutboundOrderDetailService.Repository.UpdateData(outboundOrderDetails); |
| | | |
| | | // 更新库存状态 回库单 |
| | | if (locationInfo.RoadwayNo.Contains("DW") || locationInfo.RoadwayNo.Contains("YS")) |
| | | { |
| | | AddDWANDYSRetrueOrder(stockInfo, inboundOrder); |
| | | } |
| | | else |
| | | { |
| | | AddRetrueOrder(stockInfo, inboundOrder); |
| | | } |
| | | |
| | | AddRetrueOrder(stockInfo, inboundOrder); |
| | | |
| | | |
| | | // 区分单据数据来源更新货位状态 |
| | | if (inboundOrder.System == null) |
| | | { |
| | |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | private WebResponseContent DWANDYSExecuteOutboundLogic(Dt_Task task, Dt_StockInfo stockInfo, |
| | | Dt_LocationInfo locationInfo, List<Dt_OutboundOrderDetail> outboundOrderDetails, Dt_OutboundOrder inboundOrder) |
| | | { |
| | | try |
| | | { |
| | | _unitOfWorkManage.BeginTran(); |
| | | ///更新出库单 |
| | | _outboundService.OutboundOrderService.Repository.UpdateData(inboundOrder); |
| | | // 更新出库订单详情 |
| | | _outboundService.OutboundOrderDetailService.Repository.UpdateData(outboundOrderDetails); |
| | | |
| | | // 更新库存状态 回库单 |
| | | if (locationInfo.RoadwayNo.Contains("DW") || locationInfo.RoadwayNo.Contains("YS")) |
| | | { |
| | | AddDWANDYSRetrueOrder(stockInfo, inboundOrder); |
| | | } |
| | | |
| | | // 区分单据数据来源更新货位状态 |
| | | if (inboundOrder.System == null) |
| | | { |
| | | return WebResponseContent.Instance.Error("出库单数据源为空"); |
| | | } |
| | | if (!inboundOrder.System.Equals("SMOM")) |
| | | { |
| | | UpdateLocationStatus(locationInfo); |
| | | } |
| | | // 处理任务完成 |
| | | CompleteTask(task); |
| | | |
| | | // 添加状态变更记录 |
| | | AddStatusChangeRecord(task, stockInfo, locationInfo); |
| | | |
| | | // 根据订单类型处理不同逻辑 |
| | | |
| | | var outboundOrder = _outboundService.OutboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .Where(x => x.OrderNo == inboundOrder.OrderNo).First(); |
| | | foreach(var outboundOrderDetail in outboundOrderDetails) |
| | | { |
| | | var outDetail = _outboundService.OutboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .Where(x => x.OrderId == outboundOrder.Id && x.BatchNo == outboundOrderDetail.BatchNo).First(); |
| | | string path = "http://fr.mankun.com:8080/webroot/decision/view/report?viewlet=fr-report\\SMOM/Product/Produce/OutBoundDetileReport.cpt&op=write&format=pdf"; |
| | | string fullPath = AppDomain.CurrentDomain.BaseDirectory; |
| | | var url = Path.Combine(fullPath, "wwwroot", "Reports"); |
| | | string savePath = Path.Combine(url, "本次出库.pdf"); |
| | | |
| | | |
| | | if (outboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt() && inboundOrder.System.Equals("ERP")) |
| | | { |
| | | FeedBackOutERP(outboundOrder.OrderNo, outboundOrderDetail.LinId); |
| | | DownloadReport(path, savePath, outboundOrderDetail.Id); |
| | | } |
| | | ///单据完成推送SMOM系统 |
| | | if (outboundOrder.OrderStatus == OutboundStatusEnum.出库完成.ObjToInt() && inboundOrder.System.Equals("SMOM")) |
| | | { |
| | | var stockInfoDetail = stockInfo.Details.FirstOrDefault(); |
| | | ProcessNormalOutbound(task, stockInfo, outboundOrder, outDetail); |
| | | //DownloadReport(path, savePath, outboundOrderDetails.Id); |
| | | //printTest(savePath); |
| | | //SendNormalOutboundToWMS(task, outboundOrder, stockInfoDetail, outDetail); |
| | | } |
| | | |
| | | if (outboundOrder.OrderType == 240) // 盘点出库 |
| | | { |
| | | // 盘点出库特殊处理逻辑 |
| | | } |
| | | } |
| | | _unitOfWorkManage.CommitTran(); |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | catch |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | throw; |
| | | } |
| | | } |
| | | private void UpdateOutboundOrderDetails(Dt_StockInfo stockInfo, Dt_OutboundOrder inboundOrder, ref Dt_OutboundOrderDetail inboundOrderDetail) |
| | | { |
| | | int overCount = inboundOrder.Details.Count(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()); |
| | |
| | | } |
| | | |
| | | //低温、药水 |
| | | private void DWANDYSUpdateOutboundOrderDetails(Dt_StockInfo stockInfo, Dt_OutboundOrder inboundOrder, ref Dt_OutboundOrderDetail inboundOrderDetail) |
| | | private void DWANDYSUpdateOutboundOrderDetails(Dt_StockInfo stockInfo, Dt_OutboundOrder inboundOrder, ref List<Dt_OutboundOrderDetail> inboundOrderDetails) |
| | | { |
| | | string BatchNo = inboundOrderDetail.BatchNo; |
| | | int overCount = inboundOrder.Details.Where(x => x.BatchNo == BatchNo).Count(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()); |
| | | //inboundOrderDetail = inboundOrder.Details.FirstOrDefault(x => x.BatchNo == stockInfo.Details.FirstOrDefault()?.BatchNo&&x.LPNNo==stockInfo.PalletCode); |
| | | |
| | | foreach (var item in stockInfo.Details) |
| | | List<Dt_OutboundOrderDetail> newOutboundOrderDetails = inboundOrderDetails; |
| | | int overCount = inboundOrder.Details.Count(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()); |
| | | foreach (var newOutboundOrderDetail in newOutboundOrderDetails) |
| | | { |
| | | if (inboundOrderDetail == null) continue; |
| | | string BatchNo = newOutboundOrderDetail.BatchNo; |
| | | //inboundOrderDetail = inboundOrder.Details.FirstOrDefault(x => x.BatchNo == stockInfo.Details.FirstOrDefault()?.BatchNo&&x.LPNNo==stockInfo.PalletCode); |
| | | |
| | | if (inboundOrderDetail.BatchNo == item.BatchNo) |
| | | foreach (var item in stockInfo.Details) |
| | | { |
| | | inboundOrderDetail.OverOutQuantity += item.OutboundQuantity; |
| | | if (newOutboundOrderDetail == null) continue; |
| | | |
| | | if (inboundOrderDetail.OverOutQuantity == inboundOrderDetail.OrderQuantity) |
| | | if (newOutboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()) continue; |
| | | |
| | | if (newOutboundOrderDetail.BatchNo == item.BatchNo) |
| | | { |
| | | inboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); |
| | | overCount++; |
| | | } |
| | | else if (inboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) |
| | | { |
| | | inboundOrderDetail.OrderDetailStatus = OutboundStatusEnum.出库中.ObjToInt(); |
| | | inboundOrder.OrderStatus = OutboundStatusEnum.出库中.ObjToInt(); |
| | | newOutboundOrderDetail.OverOutQuantity += item.OutboundQuantity; |
| | | |
| | | if (newOutboundOrderDetail.OverOutQuantity == newOutboundOrderDetail.OrderQuantity) |
| | | { |
| | | newOutboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); |
| | | overCount++; |
| | | } |
| | | else if (newOutboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) |
| | | { |
| | | newOutboundOrderDetail.OrderDetailStatus = OutboundStatusEnum.出库中.ObjToInt(); |
| | | inboundOrder.OrderStatus = OutboundStatusEnum.出库中.ObjToInt(); |
| | | } |
| | | } |
| | | } |
| | | if (inboundOrder.Details.Count() == overCount) |
| | | { |
| | | inboundOrder.OrderStatus = OutboundStatusEnum.出库完成.ObjToInt(); |
| | | } |
| | | } |
| | | if (inboundOrder.Details.Count == overCount) |
| | | { |
| | | inboundOrder.OrderStatus = OutboundStatusEnum.出库完成.ObjToInt(); |
| | | } |
| | | |
| | | } |
| | | |
| | | private void DeleteAndMoveIntoHtStockStatus(Dt_StockInfo stockInfo) |
| | |
| | | } |
| | | } |
| | | |
| | | 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(); |
| | | |
| | | PrintUsingSpireSimple(fullPath, printerName); |
| | | if (string.IsNullOrEmpty(printerName)) |
| | | { |
| | | // 如果没有配置,使用系统默认打印机 |
| | | printerName = GetDefaultPrinterUbuntu(); |
| | | } |
| | | |
| | | |
| | | Console.WriteLine("所有打印方法都失败"); |
| | | PrintUsingUbuntuPrinter(fullPath, printerName); |
| | | } |
| | | |
| | | |
| | | private void PrintUsingSpireSimple(string filePath, string printerName) |
| | | /// <summary> |
| | | /// 获取 Ubuntu 默认打印机 |
| | | /// </summary> |
| | | private string GetDefaultPrinterUbuntu() |
| | | { |
| | | try |
| | | { |
| | | using (Spire.Pdf.PdfDocument pdf = new Spire.Pdf.PdfDocument()) |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | // 加载文件 |
| | | pdf.LoadFromFile(filePath); |
| | | FileName = "lpstat", |
| | | Arguments = "-d", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | RedirectStandardOutput = true |
| | | }; |
| | | |
| | | // 获取实际的打印机名称 |
| | | string actualPrinterName = GetActualPrinterName(printerName); |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | process.Start(); |
| | | string output = process.StandardOutput.ReadToEnd(); |
| | | process.WaitForExit(); |
| | | |
| | | Console.WriteLine($"配置的打印机名称: {printerName}"); |
| | | Console.WriteLine($"实际使用的打印机名称: {actualPrinterName}"); |
| | | |
| | | // 如果找不到实际打印机,使用默认打印机 |
| | | if (!string.IsNullOrEmpty(actualPrinterName) && IsPrinterInstalled(actualPrinterName)) |
| | | // 解析默认打印机名称,例如: "system default destination: LenovoPrinter" |
| | | if (output.Contains(":")) |
| | | { |
| | | pdf.PrintSettings.PrinterName = actualPrinterName; |
| | | Console.WriteLine($"✓ 已设置打印机: {actualPrinterName}"); |
| | | return output.Split(':')[1].Trim(); |
| | | } |
| | | else |
| | | { |
| | | Console.WriteLine($"⚠️ 打印机 '{actualPrinterName}' 未找到,使用默认打印机"); |
| | | } |
| | | |
| | | // 直接打印 |
| | | pdf.Print(); |
| | | Console.WriteLine("✓ 打印任务已提交成功"); |
| | | return "LenovoPrinter"; // 默认回退 |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | return "LenovoPrinter"; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Ubuntu 打印实现 |
| | | /// </summary> |
| | | private void PrintUsingUbuntuPrinter(string filePath, string printerName) |
| | | { |
| | | try |
| | | { |
| | | PrintWithLpr(filePath, printerName); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"✗ Spire.PDF打印失败: {ex.Message}"); |
| | | |
| | | // 输出所有可用打印机,帮助调试 |
| | | Console.WriteLine("\n系统所有可用打印机:"); |
| | | foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters) |
| | | { |
| | | Console.WriteLine($" - {printer}"); |
| | | } |
| | | |
| | | Console.WriteLine($"✗ 打印失败: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 从配置的友好名称获取实际的打印机名称 |
| | | /// 使用 lpr 命令打印 |
| | | /// </summary> |
| | | private string GetActualPrinterName(string displayName) |
| | | private void PrintWithLpr(string filePath, string printerName) |
| | | { |
| | | if (string.IsNullOrEmpty(displayName)) |
| | | return string.Empty; |
| | | Console.WriteLine($"📄 正在打印到 {printerName}: {Path.GetFileName(filePath)}"); |
| | | |
| | | // 如果配置的是 "192.168.99.3 上的 Lenovo M7605D" |
| | | if (displayName.Contains("192.168.99.3 上的 Lenovo M7605D")) |
| | | { |
| | | // 在系统中查找实际的打印机名称 |
| | | return FindActualPrinterForIP("192.168.99.3"); |
| | | } |
| | | string command = $"lpr -P {printerName} \"{filePath}\""; |
| | | |
| | | // 如果直接配置的是IP地址 |
| | | if (displayName.Contains("192.168.99.3")) |
| | | { |
| | | return FindActualPrinterForIP("192.168.99.3"); |
| | | } |
| | | |
| | | // 如果已经是实际的打印机名称,直接返回 |
| | | if (IsPrinterInstalled(displayName)) |
| | | { |
| | | return displayName; |
| | | } |
| | | |
| | | // 默认返回原名称 |
| | | return displayName; |
| | | ExecuteShellCommand(command); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 查找IP地址对应的实际打印机名称 |
| | | /// 执行 Shell 命令 |
| | | /// </summary> |
| | | private string FindActualPrinterForIP(string ipAddress) |
| | | private void ExecuteShellCommand(string command) |
| | | { |
| | | try |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | // 获取所有打印机 |
| | | var allPrinters = new List<string>(); |
| | | foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters) |
| | | { |
| | | allPrinters.Add(printer); |
| | | } |
| | | FileName = "/bin/bash", |
| | | Arguments = $"-c \"{command.Replace("\"", "\\\"")}\"", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | RedirectStandardOutput = true, |
| | | RedirectStandardError = true |
| | | }; |
| | | |
| | | 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) |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | Console.WriteLine($"查找打印机失败: {ex.Message}"); |
| | | return string.Empty; |
| | | 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> |
| | | private bool IsPrinterInstalled(string printerName) |
| | | /// <summary> |
| | | /// Ubuntu 打印方法 - 使用 lpr 命令 |
| | | /// </summary> |
| | | private void PrintUsingConfiguredPrinter(string filePath, string printerName) |
| | | { |
| | | try |
| | | { |
| | | foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters) |
| | | // 1. 检查打印机是否在线 |
| | | if (!IsPrinterAvailableUbuntu(printerName)) |
| | | { |
| | | if (printer.Equals(printerName, StringComparison.OrdinalIgnoreCase)) |
| | | { |
| | | return true; |
| | | } |
| | | throw new InvalidOperationException($"打印机 '{printerName}' 不可用或未找到"); |
| | | } |
| | | return false; |
| | | } |
| | | catch |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 使用原始打印命令 |
| | | /// </summary> |
| | | private void PrintUsingRawCommand(string filePath, string printerName) |
| | | { |
| | | try |
| | | { |
| | | var processStartInfo = new System.Diagnostics.ProcessStartInfo |
| | | |
| | | Console.WriteLine($"✓ 使用打印机: {printerName}"); |
| | | Console.WriteLine($"✓ 正在打印: {Path.GetFileName(filePath)}"); |
| | | |
| | | // 2. 使用 lpr 命令打印 |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | FileName = filePath, |
| | | Verb = "print", // 使用"print"动词 |
| | | UseShellExecute = true, // 关键:启用Shell执行 |
| | | FileName = "lpr", |
| | | Arguments = $"-P {printerName} \"{filePath}\"", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden |
| | | RedirectStandardOutput = true, |
| | | RedirectStandardError = true |
| | | }; |
| | | |
| | | // 设置打印机(可选,系统通常会使用默认打印机) |
| | | // processStartInfo.Arguments = $"/t \"{filePath}\" \"{printerName}\""; |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | process.Start(); |
| | | string output = process.StandardOutput.ReadToEnd(); |
| | | string error = process.StandardError.ReadToEnd(); |
| | | process.WaitForExit(); |
| | | |
| | | System.Diagnostics.Process.Start(processStartInfo); |
| | | if (process.ExitCode == 0) |
| | | { |
| | | Console.WriteLine($"✓ 打印任务已提交到 {printerName}"); |
| | | } |
| | | else |
| | | { |
| | | throw new InvalidOperationException($"打印失败: {error}"); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"打印失败: {ex.Message}"); |
| | | // 可以尝试其他方法 |
| | | //TryAlternativePrintMethod(filePath, printerName); |
| | | Console.WriteLine($"✗ 打印失败: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 检查文件是否可访问 |
| | | /// Ubuntu 检查打印机可用性 |
| | | /// </summary> |
| | | private bool IsFileAccessible(string filePath) |
| | | private bool IsPrinterAvailableUbuntu(string printerName) |
| | | { |
| | | try |
| | | { |
| | | using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) |
| | | ProcessStartInfo psi = new ProcessStartInfo |
| | | { |
| | | return fs.Length > 0; |
| | | FileName = "lpstat", |
| | | Arguments = $"-p {printerName}", |
| | | UseShellExecute = false, |
| | | CreateNoWindow = true, |
| | | RedirectStandardOutput = true |
| | | }; |
| | | |
| | | using (Process process = new Process { StartInfo = psi }) |
| | | { |
| | | 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> |