using BO; using BO.BO.Bill; using BO.Utils; using BO.Utils.BillRpc; using BWP.WinFormControl; using BWP.WinFormControl.WeightDataFormat; 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; namespace WeighAndGrading { public partial class GradeFrom : Form, IAfterLogin { #region IAfterLogin public string RoleName { get { return "定级员"; } } public Form Generate() { return this; } #endregion private delegate void InvokeHandler(); List list; List details; SerialPort weightPort; int maxIndex = 0; Thread syncWegithThread; readonly ConcurrentQueue _detailQueue = new ConcurrentQueue(); readonly ConcurrentQueue _weightQueue = new ConcurrentQueue(); #region weightNeed private IDataFormat _dataFormat; private Thread _inQueryThread, _outQueryThread; private bool _mainProcessIsRun; readonly StringBuilder _dataStrBuilder = new StringBuilder(); readonly ConcurrentQueue _dataQueue = new ConcurrentQueue(); private const int WmUpdDisplayMessage = 0x0500 + 2; private string _displayValue; private int _mainHandle; #endregion int MainHandle { get { if (_mainHandle == 0) { _mainHandle = WinApiSendMessage.FindWindow(null, this.Text); } return _mainHandle; } } public GradeFrom() { InitializeComponent(); butcherTimeInput.Date = beginDateInput.Date = endDataInput.Date = DateTime.Today; dataGridView.AutoGenerateColumns = false; dataGridView.DataSource = null; historyGrid.AutoGenerateColumns = false; historyGrid.DataSource = null; AddLivestockBtn(); weightPort = new SerialPort(); syncWegithThread = new Thread(SyncTask) { IsBackground = true }; this.FormClosing += delegate { if (syncWegithThread.IsAlive) syncWegithThread.Abort(); if (_inQueryThread != null && _inQueryThread.IsAlive) DisableWeight(); }; } private void SyncTask() { while (_mainProcessIsRun) { if (_detailQueue.Any() && _weightQueue.Any()) { long id; decimal weight; if (_detailQueue.TryDequeue(out id) && _weightQueue.TryDequeue(out weight)) { GradeAndWeightRpc.FillDetailWeight(id, weight); var first = details.FirstOrDefault(x => x.ID == id); if (first != null) { first.Weight = weight; this.Invoke(new InvokeHandler(delegate() { historyGrid.Refresh(); })); } } } else Thread.Sleep(1000); } } void AddLivestockBtn() { var livestocks = BaseInfoRpcUtil.GetLivestockList(); foreach (var item in livestocks) { var btn = new Button() { Name = "_" + item.Item1, Text = item.Item2, Tag = item, Size = new Size(70, 60), TextAlign = ContentAlignment.MiddleCenter, Margin = new Padding { All = 10 }, Font = new Font("宋体", 15) }; btn.Click += (sender, e) => { var selectRows = GetEnableTopTowRows(); if (selectRows.Count == 0) throw new Exception("没有可定级的数据记录了"); var livestock = (CTuple)btn.Tag; var tech = livestock.Item3 == 0 ? "烫褪" : "毛剥"; var targetRow = selectRows.FirstOrDefault(x => x.Cells["D_Technics_Name"].Value.ToString() == tech); if (targetRow == null) throw new Exception(string.Format("没有 {0} 的数据可操作", tech)); var currentRow = targetRow.DataBoundItem as GradeAndWeight; maxIndex += 1; var entity = new GradeAndWeight_Detail(); entity.Index = maxIndex; entity.OrderDetail_ID = currentRow.OrderDetail_ID; entity.Order = currentRow.Order; entity.Livestock_ID = livestock.Item1; entity.Livestock_Name = livestock.Item2; entity.Technics = livestock.Item3; entity.Technics_Name = livestock.Item3 == 0 ? "烫褪" : "毛剥"; entity.Time = DateTime.Now; details.Insert(0, entity); GradeAndWeightRpc.InsertDetail(entity); _detailQueue.Enqueue(entity.ID); currentRow.Already = currentRow.Already + 1; BindDataGrid(); historyGrid.DataSource = null; historyGrid.DataSource = details; historyGrid.Refresh(); //var name = livestock.Technics == 0 ? "带皮白条" : "去皮白条"; //Print(name, entity.Index); }; if (item.Item3 == 0) ttPanel.Controls.Add(btn); else mbPanel.Controls.Add(btn); } } bool queryPanelShow = false; private void saiXuanBtn_Click(object sender, EventArgs e) { if (queryPanelShow) Animate.AnimateWindow(queryPanel.Handle, 200, Animate.AW_HIDE + Animate.AW_VER_NEGATIVE); else Animate.AnimateWindow(queryPanel.Handle, 200, Animate.AW_SLIDE + Animate.AW_VER_POSITIVE); queryPanelShow = !queryPanelShow; } private void queryBtn_Click(object sender, EventArgs e) { if (queryPanelShow) { Animate.AnimateWindow(queryPanel.Handle, 200, Animate.AW_HIDE + Animate.AW_VER_NEGATIVE); queryPanelShow = !queryPanelShow; } int? order = null; if (!string.IsNullOrEmpty(orderInput.Text)) { int v; if (int.TryParse(orderInput.Text, out v)) order = v; } int type = -1; if (tangRadio.Checked) type = 0; else if (maoRadio.Checked) type = 1; details = GradeAndWeightRpc.GetDetails(beginDateInput.Date.Value, beginDateInput.Date.Value, order, type); historyGrid.DataSource = null; if (details.Any()) historyGrid.DataSource = details; historyGrid.Refresh(); } private void GradeFrom_Load(object sender, EventArgs e) { queryPanel.Hide(); } private void closeBtn_Click(object sender, EventArgs e) { this.Close(); } private void syncBtn_Click(object sender, EventArgs e) { var date = butcherTimeInput.Date.Value; list = GradeAndWeightRpc.GetGradeAndWeightList(date); BindDataGrid(); details = GradeAndWeightRpc.GetDetails(date, date, null, -1); BindDetailGrid(); if (details.Any()) maxIndex = details.First().Index; } void BindDataGrid() { dataGridView.DataSource = list.OrderBy(x => new { x.Finish, x.Order }).ToList(); foreach (DataGridViewRow row in dataGridView.Rows) { if ((bool)row.Cells["D_Finish"].Value) row.DefaultCellStyle.BackColor = Color.YellowGreen; } var selectRows = GetEnableTopTowRows(); if (selectRows.Any()) { var first = selectRows.First().DataBoundItem as GradeAndWeight; orderLabel.Text = first.Order.ToString(); alreadyLabel.Text = first.Already.ToString(); } else { orderLabel.Text = alreadyLabel.Text = string.Empty; dataGridView.ClearSelection(); } dataGridView.Refresh(); } void BindDetailGrid() { historyGrid.DataSource = details; historyGrid.Refresh(); } //void BindSelectColor(GradeAndWeight entity) //{ // if (entity.Finish) // dataGridView.RowsDefaultCellStyle.SelectionBackColor = Color.FromArgb(204, 51, 51); // else // dataGridView.RowsDefaultCellStyle.SelectionBackColor = Color.FromArgb(66, 163, 218); //} private void printBtn_Click(object sender, EventArgs e) { var entity = new PrintEntity(); entity.AccountingUnit_Name = "青花瓷软件(北京)有限公司"; entity.Goods_Name = "B2/B3 ERP"; entity.Date = DateTime.Today; entity.Checker = "管理员"; entity.StoreCondition = "0-4℃ 5日"; entity.Place = "北京市海淀区"; entity.TelNumber = "010-62701591"; entity.Address = "北京市北京市海淀区知春路49号"; entity.BarCode = string.Format("BWP{0}{1:00000}", DateTime.Today.ToString("yyyyMMdd"), new Random().Next(1, 1000)); entity._2DQRCode = string.Format("http://www.bwpsoft.com?code={0}", entity.BarCode); PrintAPI.Print(entity); } private void configBtn_Click(object sender, EventArgs e) { new GradeSettingFrom().ShowDialog(); } List GetEnableTopTowRows() { var result = new List(); if (dataGridView.Rows.Count == 0) return result; string top = string.Empty; for (var i = 0; i <= dataGridView.Rows.Count - 1; i++) { var row = dataGridView.Rows[i]; if ((bool)row.Cells["D_Finish"].Value) break; var tv = row.Cells["D_Technics_Name"].Value.ToString(); if (tv != top) { row.Selected = true; result.Add(row); if (result.Count == 2) break; } top = tv; if (i == 2) break; } return result; } #region weightNeed void OpenSerialPort() { if (enableWeight.Checked) return; if (GradeContext.Config.RateSet == null) throw new Exception("请先配置称相关信息"); weightPort.PortName = GradeContext.Config.ComSet; weightPort.BaudRate = GradeContext.Config.RateSet.Value; weightPort.DataBits = GradeContext.Config.BitSet.Value; weightPort.ReadBufferSize = 4096 * 100; if (!string.IsNullOrEmpty(GradeContext.Config.Format)) format = "{0:{format}}".Replace("{format}", GradeContext.Config.Format); switch (GradeContext.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(); _outQueryThread = new Thread(OutQuery); _outQueryThread.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.Bufsize) { _dataStrBuilder.Append(c); _dataQueue.Enqueue(_dataStrBuilder.ToString()); _dataStrBuilder.Clear(); } else { _dataStrBuilder.Append(c); } } } } private void OutQuery() { while (_mainProcessIsRun) { try { bool isStatic; string str; string subStr; if (!_dataQueue.TryDequeue(out subStr)) { Thread.Sleep(1); continue; } // 解析接受的端口数据 if (_dataFormat.ParseAscii(subStr, out str, out isStatic)) { if (string.IsNullOrEmpty(str)) str = "0"; _displayValue = string.Format(format, decimal.Parse(str)); if (str != "0") _weightQueue.Enqueue(decimal.Parse(_displayValue)); WinApiSendMessage.SendMessage(MainHandle, WmUpdDisplayMessage, 0, 0); } } catch (Exception) { Thread.Sleep(1000); continue; } Thread.Sleep(1); } } void DisableWeight() { _mainProcessIsRun = false; if (syncWegithThread != null && syncWegithThread.IsAlive) syncWegithThread.Abort(); WeightValue = 0; format = "{0:0.00}"; Thread.Sleep(10); if (_inQueryThread.IsAlive) { _inQueryThread.Abort(); } if (_outQueryThread.IsAlive) { _outQueryThread.Abort(); } if (weightPort.IsOpen) weightPort.Close(); } public void enableWeight_Click(object sender, EventArgs e) { if (!enableWeight.Checked) { OpenSerialPort(); _mainProcessIsRun = true; ReadData(); if (syncWegithThread != null && !syncWegithThread.IsAlive) syncWegithThread.Start(); } else DisableWeight(); enableWeight.CheckState = enableWeight.Checked ? CheckState.Unchecked : CheckState.Checked; } decimal? WeightValue { get { if (!string.IsNullOrEmpty(lblChengZhong.Text)) return decimal.Parse(lblChengZhong.Text); return null; } set { lblChengZhong.Text = string.Format(format, value); } } protected override void DefWndProc(ref Message m) { switch (m.Msg) { case WmUpdDisplayMessage: lblChengZhong.Text = _displayValue; break; default: base.DefWndProc(ref m); break; } } #endregion } }