using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using POSV.Utils; using System.Threading.Tasks; using POSV.Entity; using POSV.Bean; using DevComponents.DotNetBar.Controls; using DevComponents.Editors; using DevComponents.DotNetBar; namespace POSV.Component { [ToolboxItem(true)] public partial class KitchenPrinter : AbstractParameter { /// /// 修改前的数据 /// private Dictionary _oldValue = new Dictionary(); /// /// 修改后的数据 /// private Dictionary _newValue = new Dictionary(); /// /// 是否初始化 /// private bool _inited = false; /// /// 下拉数字选择列表 /// private string[] _items = { "0" , "1" , "2" , "3" , "4" , "5" }; public KitchenPrinter() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (this.DesignMode) return; this.BackColor = Color.Transparent; //票头空白行数 this.comboBoxEx8.DataSource = (string[])_items.Clone(); this.comboBoxEx8.SelectedIndex = 0; //票尾空白行数 this.comboBoxEx2.DataSource = (string[])_items.Clone(); this.comboBoxEx2.SelectedIndex = 0; //厨打份数 this.comboBoxEx3.DataSource = (string[])_items.Clone(); this.comboBoxEx3.SelectedIndex = 1; //出品份数 this.comboBoxEx5.DataSource = (string[])_items.Clone(); this.comboBoxEx5.SelectedIndex = 1; //打印发送延迟 this.comboBoxEx4.DataSource = (string[])_items.Clone(); this.comboBoxEx4.SelectedIndex = 1; //票号长度 this.comboBoxEx6.DataSource = (string[])_items.Clone(); this.comboBoxEx6.SelectedIndex = 0; this.InitUi(); } /// /// 初始化界面 /// private void InitUi() { //界面加载开始 this._inited = false; Task.Factory.StartNew(() => { Dictionary data = null; lock (Global.Instance.SyncLock) { //获取品类分组下的全部参数 using (var db = Global.Instance.OpenDataBase) { data = db.Dictionary(string.Format(SqlConstant.ConfigQueryByGroupToDictionary , ConfigConstant.PERIPHERAL_GROUP)); } } //将新增加或者变更的参数重新更新到数据库 var defaultValue = ConfigConstant.PeripheralGroupDefaultValue(); //数据库有配置参数 if (data != null) { var diff = defaultValue.Where(kvp => !data.ContainsKey(kvp.Key)).ToDictionary(kvp => kvp.Key , kvp => kvp.Value); if (diff != null && diff.Keys.Count > 0) { var list = new List(); foreach (var v in diff) { var config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.Group = ConfigConstant.PERIPHERAL_GROUP; config.TenantId = Global.Instance.Authc.TenantId; config.Keys = v.Key; config.Values = v.Value; list.Add(config); } //如果数据表中没有配置group相关的信息,更新差异 this.SaveChanged(list); //将差异合并到data,避免再次访问数据库 data = data.Concat(diff).ToDictionary(x => x.Key , x => x.Value); } } else { //加载系统默认参数 data = defaultValue; var list = new List(); foreach (var v in defaultValue) { var config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.Group = ConfigConstant.PERIPHERAL_GROUP; config.TenantId = Global.Instance.Authc.TenantId; config.Keys = v.Key; config.Values = v.Value; list.Add(config); } //如果数据表中没有配置group相关的信息,保存 this.SaveChanged(list); } return data; }).ContinueWith(task => { if (task.IsFaulted) { LOGGER.Error(task.Exception.GetBaseException() , "加载厨打参数设置异常"); } else { this.Invoke(new Action(() => { BindUi(task.Result); })); } }); } private void BindUi(Dictionary data) { //变更前的数据单独存储 _oldValue.Clear(); _oldValue = ObjectUtils.Copy>(data); //清理历史变更数据 _newValue.Clear(); var lists = new List(); //取系统默认的配置 var defaultPrinterItem = Global.Instance.GetDefaultPrinterItem(); //将默认None打印机压入 lists.Add(defaultPrinterItem); //将默认参数绑定到Tag,支持更换事件的操作 this.cmbPrinter.Tag = defaultPrinterItem; //数据表中加载打印机列表 List printers = null; lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { printers = db.Query().ToList(); } } if (printers != null) { foreach (var entity in printers) { var printer = new PrinterItem(); printer.Id = entity.Id; printer.Name = entity.Name; printer.Port = entity.Port; //打印机表中没有具体参数对应的值 printer.Data = new Dictionary(); printer.DynamicLibrary = entity.DynamicLibrary; printer.Type = entity.Type; printer.InitCommand = entity.InitCommand; printer.NormalCommand = entity.NormalCommand; printer.DoubleHeightCommand = entity.DoubleHeightCommand; printer.DoubleWidthCommand = entity.DoubleWidthCommand; printer.DoubleWidthHeightCommand = entity.DoubleWidthHeightCommand; printer.CutPageCommand = entity.CutPageCommand; printer.CashboxCommand = entity.CashboxCommand; printer.UserDefined = entity.UserDefined; printer.PageWidth = entity.PageWidth; lists.Add(printer); } } //打印机列表 this.cmbPrinter.Items.Clear(); this.cmbPrinter.DisplayMember = "Name"; this.cmbPrinter.Items.AddRange(lists.ToArray()); //串口参数初始值 this.cmbSerialPort.Items.Clear(); this.cmbSerialPort.Items.AddRange(Constant.COM_PORT_NAME_VALUE); this.cmbSerialPortBaud.Items.Clear(); this.cmbSerialPortBaud.Items.AddRange(Constant.COM_PORT_BAUD_VALUE); //并口默认参数 this.cmbParallelPort.Items.Clear(); this.cmbParallelPort.Items.AddRange(Constant.LPT_NAME_VALUE); //打印机驱动默认参数 this.cmbDriverPrinter.Items.Clear(); this.cmbDriverPrinter.Items.AddRange(Global.Instance.AvailablePrinters.ToArray()); var json = data[ConfigConstant.PERIPHERAL_KITCHEN_TICKET]; var kitchenPrinterItem = JsonUtils.Deserialize>(json); string whereSql = ""; foreach (var item in kitchenPrinterItem) { string [] array = item.Key.Split('-'); whereSql += ("'"+array[0] + "',"); } List kitList = null; if (!"".Equals(whereSql)) { whereSql = whereSql.Substring(0, whereSql.Length-1); try { using (var db = Global.Instance.OpenDataBase) { kitList = db.Fetch(string.Format("select * from pos_kit_plan where no not in ({0})", whereSql)); } } catch (Exception ex) { LOGGER.Error(ex, "获取厨打方案成功"); } } if (kitList!=null && kitList.Count > 0) { foreach (KitPlan kitPlan in kitList) { //取系统默认的配置 KitchenPrinterItem newKitPrint = new KitchenPrinterItem(); newKitPrint.KitId = kitPlan.Id; newKitPrint.KitType = StringUtils.GetInt(kitPlan.Type); newKitPrint.PrinterItem = defaultPrinterItem; kitchenPrinterItem.Add(string.Format("{0}-{1}({2})", kitPlan.No, kitPlan.Name, kitPlan), newKitPrint); } } this.cmbKitPlan.DataSource = new BindingSource(kitchenPrinterItem , null); this.cmbKitPlan.DisplayMember = "Key"; //this.cmbKitPlan.ValueMember = "Value"; //将当前厨打方案临时存储,用于判断是否修改 this.cmbKitPlan.Tag = kitchenPrinterItem; //厨打方案 this.cmbKitPlan.SelectedIndex = 0; //CheckBoxX处理 foreach (Control control in this.groupPanel2.Controls) { if (control is CheckBoxX) { var item = control as CheckBoxX; var key = item.Tag.ToString(); if (data.ContainsKey(key)) { string _value = data[key].ToString(); item.Checked = _value.Equals("1"); } else { item.Checked = false; } } } //界面加载完成 this._inited = true; } public List NewChanged() { var result = new List(); //尚未初始化完成 if (!this._inited) return result; //当前选择的厨打方案 var kitplan = ((KeyValuePair)this.cmbKitPlan.SelectedValue); //当前选择的打印机 var printer = this.cmbPrinter.SelectedItem as PrinterItem; var newPrinter = new PrinterItem(); newPrinter.Id = printer.Id; newPrinter.Name = this.cmbPrinter.Text; newPrinter.Port = this.cmbPort.Text; var data = new Dictionary(); data.Add(Constant.COM_PORT_NAME , this.cmbSerialPort.Text); data.Add(Constant.COM_PORT_BAUD , this.cmbSerialPortBaud.Text); data.Add(Constant.LPT_NAME , this.cmbParallelPort.Text); data.Add(Constant.USB_PID , "0"); data.Add(Constant.USB_VID , "0"); data.Add(Constant.NET_IP_ADDRESS , this.txtIpAddressInput.Text); data.Add(Constant.DRIVE_NAME , this.cmbDriverPrinter.Text); newPrinter.Data = data; newPrinter.DynamicLibrary = printer.DynamicLibrary; newPrinter.Type = printer.Type; newPrinter.InitCommand = printer.InitCommand; newPrinter.NormalCommand = printer.NormalCommand; newPrinter.DoubleHeightCommand = printer.DoubleHeightCommand; newPrinter.DoubleWidthCommand = printer.DoubleWidthCommand; newPrinter.DoubleWidthHeightCommand = printer.DoubleWidthHeightCommand; newPrinter.CutPageCommand = printer.CutPageCommand; newPrinter.CashboxCommand = printer.CashboxCommand; newPrinter.UserDefined = printer.UserDefined; newPrinter.PageWidth = printer.PageWidth; var newValue = new KitchenPrinterItem(); if (kitplan.Value.KitId == null || !"".Equals(kitplan.Value.KitId)) { KitPlan kitPlanNew = null; string[] array = kitplan.Key.Split('-'); try { using (var db = Global.Instance.OpenDataBase) { kitPlanNew = db.FirstOrDefault(string.Format("select * from pos_kit_plan where no ='{0}'", array[0])); } } catch (Exception ex) { LOGGER.Error(ex, "获取厨打方案失败"); } if (kitPlanNew != null) { newValue.KitId = kitPlanNew.Id; newValue.KitType = StringUtils.GetInt(kitPlanNew.Type); } } else { newValue.KitId = kitplan.Value.KitId; newValue.KitType = kitplan.Value.KitType; } newValue.PrinterItem = newPrinter; int _value = 0; int.TryParse(this.comboBoxEx8.Text , out _value); newValue.HeaderEmpty = _value; _value = 0; int.TryParse(this.comboBoxEx2.Text , out _value); newValue.FooterEmpty = _value; _value = 1; int.TryParse(this.comboBoxEx3.Text , out _value); newValue.KitchenCount = _value; _value = 1; int.TryParse(this.comboBoxEx5.Text , out _value); newValue.MadeCount = _value; _value = 0; int.TryParse(this.comboBoxEx6.Text , out _value); newValue.Length = _value; _value = 1; int.TryParse(this.comboBoxEx4.Text , out _value); newValue.Delay = _value; newValue.CutPager = this.checkBoxX34.Checked ? 1 : 0; //判断是否更改,如果过更改压入到 NewValue bool isChanged = !(newValue.Equals(kitplan.Value)); if (isChanged) { var kitchens = this.cmbKitPlan.Tag as Dictionary; kitchens[kitplan.Key] = newValue; var config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.Group = ConfigConstant.PERIPHERAL_GROUP; config.TenantId = Global.Instance.Authc.TenantId; config.Keys = ConfigConstant.PERIPHERAL_KITCHEN_TICKET; config.Values = JsonUtils.Serialize(kitchens); result.Add(config); } //CheckBoxX处理 foreach (Control control in this.groupPanel2.Controls) { if (control is CheckBoxX) { var item = control as CheckBoxX; var key = item.Tag.ToString(); //忽略为空的 if (string.IsNullOrEmpty(key)) continue; var value = item.Checked ? "1" : "0"; //判断是否更改,如果过更改压入到 NewValue bool changed = !(this._oldValue.ContainsKey(key) && this._oldValue[key].Equals(value)); if (changed) { this._newValue[key] = value; } } } //转换为Config对象,便于存储 foreach (var v in this._newValue) { var config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.Group = ConfigConstant.PERIPHERAL_GROUP; config.TenantId = Global.Instance.Authc.TenantId; config.Keys = v.Key; config.Values = v.Value; result.Add(config); } return result; } private void OnKitPlanChanged(object sender , EventArgs e) { ComboBoxEx item = (ComboBoxEx)sender; //变更前的数据 var selected = ((KeyValuePair)item.SelectedValue); //if ("00-无可用厨打方案".Equals(selected.Keys)) //{ //} this.cmbPrinter.Tag = selected.Value.PrinterItem; //厨打方案对应的打印机 this.cmbPrinter.SelectedIndex = this.cmbPrinter.FindString(selected.Value.PrinterItem.Name); //触发打印机变更 OnPrinterChanged(this.cmbPrinter, e); //票头空白行数 this.comboBoxEx8.SelectedIndex = this.comboBoxEx8.FindString(selected.Value.HeaderEmpty.ToString()); //票尾空白行数 this.comboBoxEx2.SelectedIndex = this.comboBoxEx2.FindString(selected.Value.FooterEmpty.ToString()); //厨打份数 this.comboBoxEx3.SelectedIndex = this.comboBoxEx3.FindString(selected.Value.KitchenCount.ToString()); //出品份数 this.comboBoxEx5.SelectedIndex = this.comboBoxEx5.FindString(selected.Value.MadeCount.ToString()); //票号长度 this.comboBoxEx6.SelectedIndex = this.comboBoxEx6.FindString(selected.Value.Length.ToString()); //打印延迟 this.comboBoxEx4.SelectedIndex = this.comboBoxEx4.FindString(selected.Value.Delay.ToString()); //打印机带切刀,允许自动切纸 this.checkBoxX34.Checked = selected.Value.CutPager == 1 ? true : false; } public Tuple SaveChanged(List data) { bool isSuccess = true; string message = "参数更新成功"; try { lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { using (var trans = db.GetTransaction()) { foreach (var config in data) { db.Save(config); } trans.Complete(); } } } } catch (Exception ex) { isSuccess = false; message = "参数更新异常"; LOGGER.Error(ex , message); } finally { if (isSuccess) { //新修改后的参数应用后,重置OldValue,避免用户在没有切换Tab情况下,直接修改当前Tab内容 foreach (var config in data) { string key = config.Keys; string value = config.Values; this._oldValue[key] = value; if (ConfigConstant.PERIPHERAL_KITCHEN_TICKET.Equals(key)) { this.cmbKitPlan.Tag = JsonUtils.Deserialize>(value); } } this._newValue.Clear(); //更新控件UI UpdatePrinterUi(); } } return new Tuple(isSuccess , message); } private void UpdatePrinterUi() { Global.Instance.ReloadConfig(ConfigConstant.PERIPHERAL_GROUP); } private void OnPrinterChanged(object sender , EventArgs e) { ComboBoxEx item = (ComboBoxEx)sender; //当前的厨打方案对应的打印机参数 var kitchenPrinter = item.Tag as PrinterItem; //打印机数据 var printer = item.SelectedItem as PrinterItem; if (printer.UserDefined == 1) { this.ButtonAddPrinter.Enabled = true; this.ButtonDeletePrinter.Enabled = true; this.ButtonEditPrinter.Enabled = true; } else { this.ButtonAddPrinter.Enabled = true; this.ButtonDeletePrinter.Enabled = false; this.ButtonEditPrinter.Enabled = false; } //绑定端口 this.cmbPort.Items.Clear(); var items = printer.Port.Split(','); this.cmbPort.Items.AddRange(items); if (items.Contains(kitchenPrinter.Port)) { this.cmbPort.SelectedIndex = Array.IndexOf(items , kitchenPrinter.Port); } else { this.cmbPort.SelectedIndex = 0; } } private void OnIpAddressCustomClick(object sender , EventArgs e) { var item = sender as IpAddressInput; NumericKeyboard.ShowKeyboard(this , item); } private void OnPortChanged(object sender , EventArgs e) { ComboBoxEx item = (ComboBoxEx)sender; //当前的厨打方案对应的打印机参数 var kitchenPrinter = this.cmbPrinter.Tag as PrinterItem; //默认值 int inx = Array.IndexOf(Global.Instance.AvailablePrinters.ToArray() , kitchenPrinter.Data[Constant.DRIVE_NAME]); this.cmbDriverPrinter.SelectedIndex = inx < 0 ? 0 : inx; inx = Array.IndexOf(Constant.COM_PORT_NAME_VALUE , kitchenPrinter.Data[Constant.COM_PORT_NAME]); this.cmbSerialPort.SelectedIndex = inx < 0 ? 0 : inx; inx = Array.IndexOf(Constant.COM_PORT_BAUD_VALUE , kitchenPrinter.Data[Constant.COM_PORT_BAUD]); this.cmbSerialPortBaud.SelectedIndex = inx < 0 ? 0 : inx; inx = Array.IndexOf(Constant.LPT_NAME_VALUE , kitchenPrinter.Data[Constant.LPT_NAME]); this.cmbParallelPort.SelectedIndex = inx < 0 ? 0 : inx; this.txtIpAddressInput.Value = kitchenPrinter.Data[Constant.NET_IP_ADDRESS]; switch (item.Text) { case "串口": this.cmbSerialPort.Enabled = true;//串口 this.cmbSerialPortBaud.Enabled = true;//波特率 this.cmbParallelPort.Enabled = false;//并口 this.cmbDriverPrinter.Enabled = false;//驱动 this.txtIpAddressInput.Enabled = false;//网口 //打印测试页 //this.ButtonUpdateKitPlans.Enabled = true;//打印测试页 break; case "并口": this.cmbSerialPort.Enabled = false;//串口 this.cmbSerialPortBaud.Enabled = false;//波特率 this.cmbParallelPort.Enabled = true;//并口 this.cmbDriverPrinter.Enabled = false;//驱动 this.txtIpAddressInput.Enabled = false;//网口 //打印测试页 //this.ButtonUpdateKitPlans.Enabled = true; break; case "网口": this.cmbSerialPort.Enabled = false;//串口 this.cmbSerialPortBaud.Enabled = false;//波特率 this.cmbParallelPort.Enabled = false;//并口 this.cmbDriverPrinter.Enabled = false;//驱动 this.txtIpAddressInput.Enabled = true;//网口 //打印测试页 //this.ButtonUpdateKitPlans.Enabled = true; break; case "USB": this.cmbSerialPort.Enabled = false;//串口 this.cmbSerialPortBaud.Enabled = false;//波特率 this.cmbParallelPort.Enabled = false;//并口 this.cmbDriverPrinter.Enabled = false;//驱动 this.txtIpAddressInput.Enabled = false;//网口 //打印测试页 //this.ButtonUpdateKitPlans.Enabled = true; break; case "驱动": this.cmbSerialPort.Enabled = false;//串口 this.cmbSerialPortBaud.Enabled = false;//波特率 this.cmbParallelPort.Enabled = false;//并口 this.cmbDriverPrinter.Enabled = true;//驱动 this.txtIpAddressInput.Enabled = false;//网口 //打印测试页 //this.ButtonUpdateKitPlans.Enabled = true; break; default: this.cmbSerialPort.Enabled = false;//串口 this.cmbSerialPortBaud.Enabled = false;//波特率 this.cmbParallelPort.Enabled = false;//并口 this.cmbDriverPrinter.Enabled = false;//驱动 this.txtIpAddressInput.Enabled = false;//网口 //打印测试页 //this.ButtonUpdateKitPlans.Enabled = false; break; } } private void OnUpdateKitPlans(object sender , EventArgs e) { var button = (ButtonX)sender; bool isException = false; try { button.Text = "更新中..."; button.Enabled = false; //加载厨打方案列表 var maps = new Dictionary(); var kits = new List(); lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { kits = db.Query().ToList(); if (kits.Count > 0) { using (var trans = db.GetTransaction()) { foreach (var kit in kits) { string typeName = Global.Instance.GetKitchenTypeName(kit.Type); var keys = string.Format("{0}-{1}({2})" , kit.No , kit.Name , typeName); kit.Keys = keys; db.Save(kit); } db.Delete("where [group] = @0 and [keys] = @1;" , ConfigConstant.PERIPHERAL_GROUP , ConfigConstant.PERIPHERAL_KITCHEN_TICKET); trans.Complete(); } } } } this.InitUi(); } catch(Exception ex) { isException = true; LOGGER.Error( ex,"更新厨打方案异常"); } finally { if (isException) { } button.Text = "更新方案"; button.Enabled = true; } } private void OnButtonPrintTestPager(object sender , EventArgs e) { try { } catch (Exception ex) { LOGGER.Error(ex , "打印机测试发生异常"); } } private void OnButtonAddPrinterClick(object sender , EventArgs e) { var form = new EditPrinterForm(null); form.AcceptButtonClick += (o , args) => { this.InitUi(); }; form.CancelButtonClick += (o , args) => { }; TransparentForm trans = new TransparentForm(this.FindForm() , form); trans.Show(this); } private void OnButtonEditPrinterClick(object sender , EventArgs e) { //当前选择的打印机数据 var printerItem = this.cmbPrinter.SelectedItem as PrinterItem; var form = new EditPrinterForm(printerItem); form.AcceptButtonClick += (o , args) => { this.InitUi(); }; form.CancelButtonClick += (o , args) => { }; TransparentForm trans = new TransparentForm(this.FindForm() , form); trans.Show(this); } private void OnButtonDeletePrinterClick(object sender , EventArgs e) { //当前选择的打印机数据 var printerItem = this.cmbPrinter.SelectedItem as PrinterItem; bool isException = true; try { lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { using (var trans = db.GetTransaction()) { db.Delete("where id = @0 and userDefined = 1;" , printerItem.Id); trans.Complete(); } } } isException = false; } catch (Exception ex) { isException = true; LOGGER.Error(ex , "删除打印机发生异常"); } finally { if (!isException) { this.InitUi(); } } } } }