You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

525 lines
19 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Admin.Core.Common;
using Admin.Core.IService;
using Admin.Core.Model;
using Admin.Core.Model.Model_New;
using Aucma.Core.PrintTo.Common;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using FastReport;
using FastReport.DevComponents.DotNetBar;
using log4net;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace Aucma.Core.PrintTo.ViewModels
{
public partial class PrintToDevViewModel : ObservableObject
{
private static readonly log4net.ILog log = LogManager.GetLogger(typeof(PrintToDevViewModel));
protected readonly IOrderBomInfoServices _orderBomInfoServices;
protected readonly IPrintBarCodeServices _printBarCodeServices;
protected readonly IBaseBomInfoServices _baseBomInfoServices;
static List<BaseBomInfo> tmpList = new List<BaseBomInfo>();
private List<BaseBomInfo> items { get; }
private Queue<BaseBomInfo> BarcodesUnprinted { get; } = new Queue<BaseBomInfo>();
private Queue<BaseBomInfo> BarcodesPrinted { get; } = new Queue<BaseBomInfo>();
private PrintState printState { get; set; } = PrintState.Idle;//打印状态
protected bool isPrint { get; set; } = true;//打印标志
public static int _printType { get; set; }//打印类型
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
/// <param name="productCode">产品编码</param>
/// <param name="materialCode">物料编码</param>
/// <param name="materialName">型号简码</param>
/// <param name="printAmount">打印数量</param>
public PrintToDevViewModel(string order_code,string productCode, string productName, int printAmount,string printName,int printType)
{
_orderBomInfoServices = App.ServiceProvider.GetService<IOrderBomInfoServices>();
_printBarCodeServices = App.ServiceProvider.GetService<IPrintBarCodeServices>();
_baseBomInfoServices = App.ServiceProvider.GetService<IBaseBomInfoServices>();
_orderCode = order_code;
ProductCode = productCode;
ProductName = productName;
//MaterialName = materialName;
//MaterialCode= materialCode;
PrintAmount = printAmount;
PrintName = printName;
Progress = 0;
MaxProgress = printAmount;//最大数
State = "Green";
ErrorNum = 0;//异常
printState = PrintState.Printing;
SuspendEnabled = "False";//暂停打印
OperateEnabled = "True";//打印
_printType = printType;
// 非阻塞打印
Task.Run(async () =>
{
await ExecPrintAsync(productCode, printType, printAmount);
});
}
#endregion
#region 选中订单参数
#region 订单编码
private string _orderCode;
public string OrderCode { get => _orderCode; set => SetProperty(ref _orderCode, value); }
#endregion
#region 订单编码
private string _orderNo;
public string OrderNo { get => _orderNo; set => SetProperty(ref _orderNo, value); }
#endregion
#region 打印名称
private string _printName;
public string PrintName {
get => _printName;
set => SetProperty(ref _printName, value);
}
#endregion
#region 产品编码
private string _productCode;
public string ProductCode { get => _productCode; set => SetProperty(ref _productCode, value); }
#endregion
#region 产品名称
private string _productName;
public string ProductName { get => _productName; set => SetProperty(ref _productName, value); }
#endregion
#region 型号简码
private string _materialName;
public string MaterialName { get => _materialName; set => SetProperty(ref _materialName, value); }
#endregion
#region 物料编码
private string _materialCode;
public string MaterialCode { get => _materialCode; set => SetProperty(ref _materialCode, value); }
#endregion
#region 打印数量
private int _printAmount;
public int PrintAmount { get => _printAmount; set => SetProperty(ref _printAmount, value); }
#endregion
#region 异常数量
private int _errorNum;
public int ErrorNum { get => _errorNum; set => SetProperty(ref _errorNum, value); }
#endregion
#region 打印进度
private string _printProgress;
public string PrintProgress { get => _printProgress; set => SetProperty(ref _printProgress, value); }
#endregion
#region 进度条最大值
private int _maxProgress;
public int MaxProgress { get => _maxProgress; set => SetProperty(ref _maxProgress, value); }
#endregion
#region 进度条进度
private int _progress;
public int Progress { get => _progress; set => SetProperty(ref _progress, value); }
#endregion
#region 打印状态
private string _state;
public string State { get => _state; set => SetProperty(ref _state, value); }
#endregion
#region 开启、暂停状态按钮 名称
private string _stopOrStart;
public string StopOrStart { get => _stopOrStart; set => SetProperty(ref _stopOrStart, value); }
#endregion
#region 操作打印按钮状态
private string _operateEnabled;
public string OperateEnabled
{
get => _operateEnabled;
set => SetProperty(ref _operateEnabled, value);
}
#endregion
#region 操作暂停按钮状态
private string _suspendEnabled;
public string SuspendEnabled
{
get => _suspendEnabled;
set => SetProperty(ref _suspendEnabled, value);
}
#endregion
#endregion
#region 打印操作
[RelayCommand]
public void StartOperate()
{
if (string.IsNullOrEmpty(PrintName))
{
MessageBox.Show("打印名称不可为空?", "系统提醒", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.No);
return;
}
printState = PrintState.Printing;
SuspendEnabled = "True";
OperateEnabled = "False";
State = "Green";
if (isPrint)//首次打印
{
isPrint = false;
// 非阻塞打印
Task.Run(() =>
{
Print();
});
}
}
#region 暂停
[RelayCommand]
public void SuspendOperate()
{
if (MessageBox.Show("确定要暂停打印吗?", "系统提醒", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
{
isPrint = false;
printState = PrintState.Paused;
}
}
#endregion
#region 关闭当前界面
/// <summary>
/// 关闭当前界面
/// </summary>
/// <param name="parameter"></param>
[RelayCommand]
public void CloseWindow(object parameter)
{
var window = parameter as Window;
if (window == null) return;
isPrint = true;
if (printState == PrintState.Completetd)
{
WeakReferenceMessenger.Default.Send<string>("Refresh");//刷新窗口
window.Close();
return;
}
if (MessageBox.Show("确定要退出打印吗?", "系统提醒", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
{
printState = PrintState.Stopped;
WeakReferenceMessenger.Default.Send<string>("Refresh");//刷新窗口
window.Close();
}
}
#endregion
#endregion
#region 将打印数据添加到队列中
/// <summary>
/// 将打印数据添加到队列中
/// </summary>
/// <param name="orderNo">订单号</param>
/// <param name="materialCode">物料码</param>
/// <param name="planAmount">打印数量</param>
public async Task ExecPrintAsync(string productCode, int printType, int planAmount)
{
tmpList.Clear();
BaseBomInfo baseBomInfo = null;
List<BaseBomInfo> orderBomInfoList = await _baseBomInfoServices.QueryAsync();
if (printType== 200)//箱体
{
GetParentID(orderBomInfoList, productCode);
//OrderBomInfo obj = await _orderBomInfoServices.FirstAsync(d => d.MaterialCode == materialCode);
if (tmpList.Count() == 0)
{
MessageBox.Show("无法查询打印条码数据", "系统提醒");
return;
}
baseBomInfo= tmpList.FirstOrDefault(d=>d.MaterialType== "200");
ProductCode = baseBomInfo.MaterialCode;
ProductName = baseBomInfo.MaterialName;
}
if (printType == 500)//内胆
{
GetParentID(orderBomInfoList, productCode);
if (tmpList.Count() == 0)
{
MessageBox.Show("无法查询打印条码数据,数据为空!", "系统提醒");
return;
}
baseBomInfo = tmpList.FirstOrDefault(d => d.MaterialType == "500");
ProductCode = baseBomInfo.MaterialCode;
ProductName = baseBomInfo.MaterialName;
}
if (baseBomInfo == null)
{
MessageBox.Show("无法查询打印条码数据,数据为空", "系统提醒");
return;
}
for (int i = 0; i < planAmount; i++) { BarcodesUnprinted.Enqueue(baseBomInfo); }
}
#endregion
#region 打印
public void Print()
{
try
{
string printer = Appsettings.app("Printer", "PrinterName");
int i = 1;
while (BarcodesUnprinted.Count > 0)
{
if (printState == PrintState.Paused)
{
SetPaused();
continue;
}
if (printState == PrintState.Completetd) break;
PrintBarCode printBarCode = new PrintBarCode();
try
{
var item = BarcodesUnprinted.Peek();
string barCode = string.Empty;
if (_printType== 200)
{
barCode = GetMaxNumAsync(item.MaterialCode,"B").Result;//最大值+1
if (string.IsNullOrEmpty(barCode))
{
printState = PrintState.Paused;
SetPaused();
continue;
}
//barCode = $"B{DateTime.Now.ToString("yyMMdd")}{item.MaterialCode}{rowNum}";
PrintProgress = $"[{PrintAmount}/{i}] {barCode}";
printBarCode.MaterialBarcode = barCode;
printBarCode.PrintBarType = 1;
Console.WriteLine($"{barCode}");
}
if (_printType == 500)
{
barCode = GetMaxNumAsync(item.MaterialCode, "L").Result;//最大值+1
if (string.IsNullOrEmpty(barCode))
{
printState = PrintState.Paused;
SetPaused();
continue;
}
// barCode = $"L{DateTime.Now.ToString("yyMMdd")}{item.MaterialCode}{rowNum}";
PrintProgress = $"[{PrintAmount}/{i}] {barCode}";
printBarCode.MaterialBarcode = barCode;
printBarCode.PrintBarType = 2;//内胆码
Console.WriteLine($"{barCode}");
}
#region 打印
//对接打印机
Report barReport = new Report();
barReport.Load(System.Environment.CurrentDirectory + @"\Report\MaterialBar.frx");//打印报表位置
// 设置打印机和打印选项
barReport.PrintSettings.ShowDialog = false; // 是否打开打印机选择框
barReport.PrintSettings.Printer = printer; // 设置打印机名称
barReport.PrintSettings.Copies = 1; // 设置打印份数
//barReport.PrintSettings.PageRange = "1-3"; // 设置打印页范围
barReport.SetParameterValue("BoxBarData.Id", barCode);
barReport.SetParameterValue("BoxBarData.Order_No", _orderCode);//订单号
barReport.SetParameterValue("BoxBarData.Order_Material_Name", PrintName);//物料简码
barReport.SetParameterValue("BoxBarData.Bar_Code", barCode);//二维码
//barReport.Prepare();
//string BarPath = System.Environment.CurrentDirectory + @"\pdf\" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";
//barReport.Export(new PDFExport(), BarPath);
barReport.Print();
#endregion
printBarCode.OrderCode = _orderCode;
printBarCode.MaterialCode = item.MaterialCode;
printBarCode.MaterialName = item.MaterialName;
printBarCode.PrintTime = DateTime.Now;
printBarCode.SupplementMaterial =0;
if (string.IsNullOrEmpty(printBarCode.MaterialBarcode))
{
throw new Exception("条码生成异常");//抛出异常,回滚事务,事务退出
}
var num= _printBarCodeServices.AddAsync(printBarCode).Result;
if (num<=0)
{
Console.WriteLine($"数据已保存【订单:{printBarCode.OrderCode}》条码:{printBarCode.MaterialBarcode}】");
BarcodesPrinted.Enqueue(BarcodesUnprinted.Dequeue());
}
else
{
ErrorNum++;
log.Error($"打印保存出错:{printBarCode.ToJson()}");
}
}
catch (Exception ex)
{
log.Error($"打印出错:{ex.Message}\n{printBarCode.ToJson()}");
ErrorNum++;
}
Thread.Sleep(200);
Progress = i;
i++;
}
//打印完成
SetCompletetd();
}
catch (Exception ex)
{
log.Error($"打印出错:{ex.Message}");
}
finally
{
isPrint = true;
}
}
#region 获取最大值
/// <summary>
/// 获取最大值
/// </summary>
/// <param name="MaterialCode"></param>
/// <returns></returns>
public async Task<string> GetMaxNumAsync(string MaterialCode,string falg)
{
string barCode = $"{falg}{DateTime.Now.ToString("yyMMdd")}{MaterialCode}";
try
{
List<int> tempList = new List<int>();
var list = await _printBarCodeServices.QueryAsync(d => d.MaterialBarcode.Contains(barCode) );
if (list.Count() == 0)
{
return barCode+"0001";
}
foreach (var item in list)
{
string code = item.MaterialBarcode.Substring(item.MaterialBarcode.Length - 4);
int num = Convert.ToInt32(code);
tempList.Add(num);
}
int row = tempList.Max() + 1;
if (row==10000)
{
MessageBox.Show("订单打印数据已经超过10000无法查询打印条码数据。", "系统提醒");
return null;
}
string maxStr = (tempList.Max() + 1).ToString();
string rowNum = maxStr.PadLeft(4, '0');
return barCode+rowNum;
}
catch
{
return barCode+"0001";
}
}
#endregion
#endregion
#region 暂停
/// <summary>
/// 暂停
/// </summary>
private void SetPaused()
{
printState = PrintState.Paused;
State = "yellow";
isPrint = false;
SuspendEnabled = "False";
OperateEnabled = "True";
}
#endregion
#region 完成
/// <summary>
/// 暂停
/// </summary>
private void SetCompletetd()
{
printState = PrintState.Completetd;
State = "Green";
StopOrStart = "已完成";
isPrint = false;
OperateEnabled = "True";
}
#endregion
#region 递归获取内胆、箱体数量
public static void GetParentID(List<BaseBomInfo> treeNodes, string materialCode)
{
if (string.IsNullOrEmpty(materialCode))
{
return;
}
var query = from c in treeNodes
where c.ParentId == materialCode
select c;
foreach (var item in query)
{
if (item.MaterialType== _printType.ToString())
{
tmpList.Add(item);
}
else
{
GetParentID(treeNodes, item.MaterialCode);
}
}
}
#endregion
}
}