using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using BO.Utils; using BWP.WinFormControl.WeightDataFormat; using SegmentationWeight.Rpc; using SegmentationWeight.Rpc.Dto; namespace SegmentationWeight { public partial class SegmentationWeightForm : Form,IAfterLogin { #region weightNeed SerialPort weightPort; private IDataFormat _dataFormat; private Thread _inQueryThread; private bool _mainProcessIsRun; readonly StringBuilder _dataStrBuilder = new StringBuilder(); #endregion List mSetList = XmlUtil.DeserializeFromFile>(SegmentationWeightGoodsSetForm.SegmentationWeightGoodsSetFileName).Where(x => x.IsSelected).ToList(); BindingList mWeightRecords; public SegmentationWeightForm() { InitializeComponent(); weightPort = new SerialPort(); this.FormClosing += delegate { if (_inQueryThread != null && _inQueryThread.IsAlive) DisableWeight(); // if (syncWork != null && syncWork.IsAlive) // syncWork.Abort(); // if (syncToServer != null && syncToServer.IsAlive) // syncToServer.Abort(); }; } #region weightNeed void OpenSerialPort() { if (enableWeight.Checked) return; if (SegmentationWeightContext.Config.RateSet == null) throw new Exception("请先配置称相关信息"); weightPort.PortName = SegmentationWeightContext.Config.ComSet; weightPort.BaudRate = SegmentationWeightContext.Config.RateSet.Value; weightPort.DataBits = SegmentationWeightContext.Config.BitSet.Value; weightPort.ReadBufferSize = 4096 * 100; if (!string.IsNullOrEmpty(SegmentationWeightContext.Config.Format)) format = "{0:{format}}".Replace("{format}", SegmentationWeightContext.Config.Format); switch (SegmentationWeightContext.Config.WeightSet) { case "IND560": _dataFormat = new IND560DataFormat(); break; case "Xk3124": _dataFormat = new Xk3124DataFormat(); break; case "Xk3190A9": _dataFormat = new Xk3190A9DataFormat(); break; default: _dataFormat = new Xk3190D10DataFormat(); break; } if (!weightPort.IsOpen) { try { weightPort.Open(); } catch (InvalidOperationException) { MessageBox.Show(@"指定的端口已打开"); } catch (UnauthorizedAccessException) { MessageBox.Show(@"对端口的访问被拒绝"); } } } void ReadData() { _inQueryThread = new Thread(InQuery); _inQueryThread.Start(); } string format = "{0:0.00}"; private void InQuery() { while (_mainProcessIsRun) { int availableCount = weightPort.BytesToRead; if (availableCount == 0) { Thread.Sleep(1); } char[] buffer = new char[availableCount]; if (!weightPort.IsOpen) { continue; } weightPort.Read(buffer, 0, availableCount); foreach (var c in buffer) { if (c == _dataFormat.Beginchar) { _dataStrBuilder.Clear(); _dataStrBuilder.Append(c); } else if (c == _dataFormat.Endchar && _dataStrBuilder.Length == _dataFormat.DataLength - 1) { _dataStrBuilder.Append(c); bool isStatic; string str; if (_dataFormat.ParseAscii(_dataStrBuilder.ToString(), out str, out isStatic)) { if (SegmentationWeightContext.Config.WeightType == 0) { if (string.IsNullOrEmpty(str)) str = "0"; this.Invoke(new Action(delegate () { lblChengZhong.Text = string.Format(format, decimal.Parse(str)); if (str != "0") { //doInsertUnSubmit("", decimal.Parse(lblChengZhong.Text)); //todo 这里不需要逻辑 点击存货的时候判断是否在误差范围内 } })); } else { decimal num = 0; if (decimal.TryParse(str, out num)) { this.Invoke(new Action(delegate () { lblChengZhong.Text = string.Format(format, num); })); // LocalGradeAndWeightBL.SaveWeightData(num); WeighAvgControl.Add(num, isStatic); } if (WeighAvgControl.TryGetValue(out num)) { this.Invoke(new Action(delegate () { //lblChengZhong.Text = string.Format(format, num); if (str != "0") { //doInsertUnSubmit("", decimal.Parse(string.Format(format, num))); //todo 这里不需要逻辑 点击存货的时候判断是否在误差范围内 } })); } } } _dataStrBuilder.Clear(); } else if (_dataStrBuilder.Length != 0) { _dataStrBuilder.Append(c); } } } } private class WeighAvgControl { public static bool TryGetValue(out decimal result) { List> list; if (mWeighList.TryDequeue(out list)) { var r = list.Where(x => x.Item2).Select(x => x.Item1).GroupBy(x => x); var firstOrDefault = r.OrderByDescending(x => x.Count()).FirstOrDefault(); if (firstOrDefault != null) { result = firstOrDefault.Key; return true; } result = 0; return false; } result = 0; return false; } static ConcurrentQueue>> mWeighList = new ConcurrentQueue>>(); static List> _list = new List>(); public static void Add(decimal value, bool isStatic) { if (value >= SegmentationWeightContext.Config.MinWeight && value <= SegmentationWeightContext.Config.MaxWeight) { _list.Add(new Tuple(value, isStatic)); } else { if (_list.Count > 0) { mWeighList.Enqueue(_list); _list = new List>(); } } } } void DisableWeight() { _mainProcessIsRun = false; lblChengZhong.Text = string.Format(format, 0); format = "{0:0.00}"; Thread.Sleep(10); if (_inQueryThread.IsAlive) { _inQueryThread.Abort(); } if (weightPort.IsOpen) weightPort.Close(); } public void enableWeight_Click(object sender, EventArgs e) { if (!enableWeight.Checked) { OpenSerialPort(); _mainProcessIsRun = true; ReadData(); } else { DisableWeight(); } enableWeight.CheckState = enableWeight.Checked ? CheckState.Unchecked : CheckState.Checked; } #endregion private void btnGoodsSet_Click(object sender, EventArgs e) { var f=new SegmentationWeightGoodsSetForm(); if (f.ShowDialog() == DialogResult.OK) { InitControl(); } } private void SegmentationWeightForm_Load(object sender, EventArgs e) { mWeightRecords=new BindingList();//以后可能取数据库中没做完的,比如做着做着突然断点 RefreshUi(); InitControl(); } private void InitControl() { if (mSetList.Count < 1) { return; } flpClass.Controls.Clear(); foreach (IGrouping grouping in mSetList.GroupBy(x=>x.Name)) { var btnClass = CreateClassButton(grouping.Key); flpClass.Controls.Add(btnClass); } } private Button CreateClassButton(string text) { var btn=new Button(); btn.Text = text; btn.Click += Btn_Click; return btn; } private void Btn_Click(object sender, EventArgs e) { var text = (sender as Button).Text; foreach (Button cbutton in flpClass.Controls) { if (cbutton.Text == text) { cbutton.BackColor=Color.Aqua; } else { cbutton.BackColor = SystemColors.Control; } } flpGoods.Controls.Clear(); foreach (SegmentationWeightGoodSet set in mSetList.Where(x=>x.Name==text)) { var btnGoods = CreateGoodsButton(set); flpGoods.Controls.Add(btnGoods); } } private Button CreateGoodsButton(SegmentationWeightGoodSet set) { var btn=new Button(); btn.Text = set.Goods_Name; btn.Tag = set; btn.Click += BtnGoods_Click; return btn; } private void BtnGoods_Click(object sender, EventArgs e) { var btn = sender as Button; var set = btn.Tag as SegmentationWeightGoodSet; //todo 打印条码 要判断误差 var weight = 100m; //添加记录 var record = GetRecordBySet(set,weight); var id=SegmentationWeightRecordRpc.Insert(record); record.ID = id; mWeightRecords.Add(record); RefreshUi(); } private SegmentationWeightRecord GetRecordBySet(SegmentationWeightGoodSet set,decimal maoWeight) { var record=new SegmentationWeightRecord(); record.Goods_ID = set.Goods_ID; record.BarCode = "";//todo 条码规则 record.Goods_Name = set.Goods_Name; record.Goods_Spec = set.Goods_Spec; record.BiaoShi = "";//todo 标识 record.MaoWeight = maoWeight; record.PiWeight = 10; // record.JingWeight = record.MaoWeight - record.PiWeight; if (set.Goods_MainUnitRatio > 0) { record.JingWeight = set.Goods_MainUnitRatio; } else { record.JingWeight = record.MaoWeight - record.PiWeight; } record.CardBarCode = "车条码"; //todo return record; } void RefreshUi() { if (mWeightRecords.Count < 1) { return; } lblGoodsName.Text = mWeightRecords.First().Goods_Name; lblNumber.Text = mWeightRecords.Count.ToString(); lblWeight.Text = mWeightRecords.Sum(x => x.JingWeight).ToString(); uDataGridView1.DataSource = mWeightRecords; } public string RoleName { get { return "分割计数"; } } public Form Generate() { return this; } } }