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.Entity; using DevComponents.DotNetBar.Controls; using POSV.Utils; using System.Threading.Tasks; using POSV.Bean; using POSV.MessageEvent; namespace POSV.Component { [ToolboxItem(true)] public partial class WeightParameter : AbstractParameter { /// /// 修改前的数据 /// private Dictionary _oldValue = new Dictionary(); /// /// 修改后的数据 /// private Dictionary _newValue = new Dictionary(); /// /// 秤型号 /// private string[] steelyardBrand = Enum.GetNames(typeof(SteelyardBrandEnum)); /// /// 是否初始化 /// private bool _inited = false; public WeightParameter() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (this.DesignMode) return; this.BackColor = Color.Transparent; //秤型号 this.cmbSteelyardBrand.DataSource = steelyardBrand; this.cmbSteelyardBrand.SelectedIndex = 0; 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.STEELYARD_GROUP)); } } //将新增加或者变更的参数重新更新到数据库 var defaultValue = ConfigConstant.SteelyardGroupDefaultValue(); //数据库有配置参数 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.STEELYARD_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.STEELYARD_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(); //串口参数初始值 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); //电子秤参数 if (data.ContainsKey(ConfigConstant.STEELYARD_DEVICE_PARAMETER)) { string json = data[ConfigConstant.STEELYARD_DEVICE_PARAMETER]; var item = JsonUtils.Deserialize(json); this.cmbSteelyardBrand.Tag = item; //型号 this.cmbSteelyardBrand.SelectedIndex = this.cmbSteelyardBrand.FindString(item.Name.ToString()); //端口 this.cmbSerialPort.SelectedIndex = this.cmbSerialPort.FindString(item.Port); //波特率 this.cmbSerialPortBaud.SelectedIndex = this.cmbSerialPortBaud.FindString(item.Baud.ToString()); } else { this.cmbSteelyardBrand.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 newValue = new SteelyardParam(); newValue.Name = (SteelyardBrandEnum)Enum.Parse(typeof(SteelyardBrandEnum), this.cmbSteelyardBrand.Text); newValue.Port = this.cmbSerialPort.Text; newValue.Baud = StringUtils.GetInt(this.cmbSerialPortBaud.Text); //变更前的数据 SteelyardParam oldValue = this.cmbSteelyardBrand.Tag as SteelyardParam; //判断是否更改,如果过更改压入到 NewValue bool isChanged = !(newValue.Equals(oldValue)); if (isChanged) { var config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.Group = ConfigConstant.STEELYARD_GROUP; config.TenantId = Global.Instance.Authc.TenantId; config.Keys = ConfigConstant.STEELYARD_DEVICE_PARAMETER; config.Values = JsonUtils.Serialize(newValue); result.Add(config); } //CheckBoxX处理 foreach (Control control in 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.STEELYARD_GROUP; config.TenantId = Global.Instance.Authc.TenantId; config.Keys = v.Key; config.Values = v.Value; result.Add(config); } return result; } 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.STEELYARD_DEVICE_PARAMETER.Equals(key)) { this.cmbSteelyardBrand.Tag = JsonUtils.Deserialize(value); } } this._newValue.Clear(); Global.Instance.ReloadConfig(ConfigConstant.STEELYARD_GROUP); //更新控件UI UpdateSteelyardUi(); } } return new Tuple(isSuccess, message); } private void UpdateSteelyardUi() { //开启主界面秤连接 MsgEvent.Send(Constant.CURRENTSTEELYARD_STATUS_CHANGE, "close"); MsgEvent.Send(Constant.CURRENTSTEELYARD_STATUS_CHANGE, "start"); } /// /// 测试连接秤 /// /// /// private void OnTestSteelyardClick(object sender, EventArgs e) { //关闭当前秤 MsgEvent.Send(Constant.CURRENTSTEELYARD_STATUS_CHANGE, "close"); var name = (SteelyardBrandEnum)Enum.Parse(typeof(SteelyardBrandEnum), this.cmbSteelyardBrand.Text); var port = this.cmbSerialPort.Text; var baud = StringUtils.GetInt(this.cmbSerialPortBaud.Text); var param = new SteelyardParam(); param.Name = name; param.Port = port; param.Baud = baud; switch (name) { case SteelyardBrandEnum.大华ACS_15AB: { try { var value = WeightApi.GetAllValue(param); if (string.IsNullOrEmpty(value)) { MessageBox.Show(this, "连接失败", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show(this, "连接成功:" + value, "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { LOGGER.Error(ex, "测试连接秤异常"); } } break; case SteelyardBrandEnum.顶尖PS1X: { System.Threading.Thread.Sleep(1000); try { var value = WeightApi.GetAllValue(param); if (string.IsNullOrEmpty(value)) { MessageBox.Show(this, "连接失败", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show(this, "连接成功:" + value + " 如需使用,请重启程序", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { LOGGER.Error(ex, "测试连接秤异常"); } //开启主界面秤连接 MsgEvent.Send(Constant.CURRENTSTEELYARD_STATUS_CHANGE, "start"); } break; case SteelyardBrandEnum.顶尖PBX: { var serialPort = new SerialPortExtension(); try { //WeightUtils.Instance.CloseEngine(); System.Threading.Thread.Sleep(1000); bool result = false; serialPort.ReceiveDataEvent += (o, args) => { var data = args.ReceivedBytes; LOGGER.Info("测试接收到的操作指令返回数据:" + BitConverter.ToString(data)); if (data.Length > 0) { if (data[0] == 0x01) { //成功 result = true; } } }; var openResult = serialPort.Open(param.Port, param.Baud.ToString(), "8", "1", "0", "None"); if (openResult) { serialPort.Send(new byte[1] { 0x11 }); System.Threading.Thread.Sleep(200); if (result) { MessageBox.Show(this, "连接成功:如需使用,请重启程序", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(this, "连接失败", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show(this, "连接失败", "端口打开失败", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { LOGGER.Error(ex, "顶尖PBX测试异常"); } finally { serialPort.Close(); serialPort = null; System.Threading.Thread.Sleep(200); //WeightUtils.Instance.StartEngine(); } } break; case SteelyardBrandEnum.凯士PRPLUS404: case SteelyardBrandEnum.凯士PRPLUS216: { MessageBox.Show("请先移除秤上物品,然后点确定,2秒后,放置物品"); var serialPort = new SerialPortExtension(); var isSucc = false; try { byte[] serialBytes = new byte[0]; serialPort.ReceiveDataEvent += (o, args) => { var bytes = args.ReceivedBytes; //var hex = BitConverter.ToString(bytes, 0).Replace("-", string.Empty); //var recv = BitConverter.ToString(bytes); //Console.WriteLine("Received Data<{0}>:{1} ", e.ReceivedBytes.Length, recv); if (bytes.Length > 0) { if (bytes.Length > 1 && bytes[0] == 0x0A && bytes[1] == 0x0D) { serialBytes = new byte[0]; serialBytes = serialBytes.Concat(bytes).ToArray(); } else { serialBytes = serialBytes.Concat(bytes).ToArray(); //Console.WriteLine("temp:" + serialBytes.Length + ">>>>" + BitConverter.ToString(serialBytes)); if (name == SteelyardBrandEnum.凯士PRPLUS404) { if (serialBytes.Length == 25) { //重量 var weights = System.Text.Encoding.Default.GetString(serialBytes.Skip(2).Take(6).ToArray()); //单价 var prices = System.Text.Encoding.Default.GetString(serialBytes.Skip(10).Take(6).ToArray()); //总价 var amounts = System.Text.Encoding.Default.GetString(serialBytes.Skip(18).ToArray()); ; isSucc = true; } } else if (name == SteelyardBrandEnum.凯士PRPLUS216) { if (serialBytes.Length == 7) { //重量 var weights = System.Text.Encoding.Default.GetString(serialBytes.Skip(2).Take(6).ToArray()); isSucc = true; } } } } }; serialPort.Open(port, baud.ToString(), "8", "1", "0", "None"); System.Threading.Thread.Sleep(5000); serialPort.Close(); serialPort = null; if (!isSucc) { MessageBox.Show(this, "连接失败", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show(this, "连接成功!如需使用,请重启程序", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } //开启主界面秤连接 MsgEvent.Send(Constant.CURRENTSTEELYARD_STATUS_CHANGE, "start"); } catch (Exception ex) { MessageBox.Show("凯士PRPLUS检测异常!"); LOGGER.Error(ex, "测试凯士PRPLUS连接秤异常"); } } break; case SteelyardBrandEnum.龙飞C2: case SteelyardBrandEnum.龙飞C3: { try { //var param = new SteelyardParam(); //param.Name = name; //param.Port = port; //param.Baud = baud; var value = WeightApi.GetAllValue(param); if (!string.IsNullOrEmpty(value) && value.Length >= 16) { var weightStr = value.Substring(1, value.IndexOf('P') - 1); //var weight = StringUtils.GetDecimal(weightStr); var weight = DecimalUtils.ToRound(StringUtils.GetDecimal(weightStr), 3); MessageBox.Show(this, "连接成功:" + string.Format("重量:{0};如需使用,请重启程序", weight), "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(this, "连接失败", "连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { LOGGER.Error(ex, string.Format("{0}秤测试连接异常", name)); MessageBox.Show("检测异常!"); } finally { //开启主界面秤连接 MsgEvent.Send(Constant.CURRENTSTEELYARD_STATUS_CHANGE, "start"); } } break; } } } }