using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.IO.Ports; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using BO; using BO.Utils; using BO.Utils.BillRpc; using BWP.WinFormControl.WeightDataFormat; using Forks.JsonRpc.Client; using Newtonsoft.Json; using SegmentationWeight.Rpc; using SegmentationWeight.Rpc.Dto; namespace SegmentationWeight { public partial class SegmentationWeightForm : Form, IAfterLogin { private readonly string mDropDownSetsFileName = "SegmentationWeight_DropDownSets.xml"; private DropDownSets mDropDownSets; private List mProductTasks; private readonly string mProductTasksFileName = "SegmentationWeight_ProductTasks.xml"; #region weightNeed SerialPort weightPort; private IDataFormat _dataFormat; private Thread _inQueryThread; private bool _mainProcessIsRun; readonly StringBuilder _dataStrBuilder = new StringBuilder(); #endregion private List mSetList; BindingList mWeightRecords = new BindingList(); BindingList mAllWeightRecords = new BindingList(); private bool mIsNeedRefreshPlan = false; private readonly Thread _tdSyncAlreadyFromMiddleDb; private readonly Thread _tdSyncLocalToMiddleDb; private readonly Thread _tcCheckNetStatus; private readonly Thread _tcCheckSyncStatus; public SegmentationWeightForm() { InitializeComponent(); uDataGridView1.AutoGenerateColumns = false; weightPort = new SerialPort(); this.FormClosing += delegate { if (_inQueryThread != null && _inQueryThread.IsAlive) { DisableWeight(); } if (_tdSyncLocalToMiddleDb != null && _tdSyncLocalToMiddleDb.IsAlive) { _tdSyncLocalToMiddleDb.Abort(); } if (_tdSyncAlreadyFromMiddleDb != null && _tdSyncAlreadyFromMiddleDb.IsAlive) { _tdSyncAlreadyFromMiddleDb.Abort(); } if (_tcCheckNetStatus != null && _tcCheckNetStatus.IsAlive) { _tcCheckNetStatus.Abort(); } if (_tcCheckSyncStatus != null && _tcCheckSyncStatus.IsAlive) { _tcCheckSyncStatus.Abort(); } }; InitCombox(); InitPlanGoodsNumber(); _tdSyncAlreadyFromMiddleDb = new Thread(SyncAlreadyFromMiddleDb); _tdSyncAlreadyFromMiddleDb.Start(); _tdSyncLocalToMiddleDb = new Thread(SyncLocalToMiddleDb); _tdSyncLocalToMiddleDb.Start(); _tcCheckNetStatus = new Thread(CheckNetStatus); _tcCheckNetStatus.Start(); _tcCheckSyncStatus = new Thread(CheckSyncStatus); _tcCheckSyncStatus.Start(); } private void CheckSyncStatus() { while (true) { var syncSuccessed = SegmentationWeightRecordRpc.GetInstance().IsSyncSucessed(); var png = "stop.png"; if (syncSuccessed) png = "working.png"; var imgPath = Path.Combine(Application.StartupPath, "BWP.WinFormControl.dll"); var s = Assembly.LoadFile(imgPath).GetManifestResourceStream("BWP.WinFormControl.Images." + png); if (this.InvokeRequired) { this.BeginInvoke(new Action(() => { picSyncStatus.Image = Image.FromStream(s); picSyncStatus.Refresh(); })); } else { picSyncStatus.Image = Image.FromStream(s); picSyncStatus.Refresh(); } Thread.Sleep(1000); } } private bool laseConnection = false; private void CheckNetStatus() { while (true) { try { var newConnection = LoginRpcUtil.TestConnection(500); if (newConnection && laseConnection) { Thread.Sleep(1000); continue; } var png = "stop.png"; if (newConnection) png = "working.png"; var imgPath = Path.Combine(Application.StartupPath, "BWP.WinFormControl.dll"); var s = Assembly.LoadFile(imgPath).GetManifestResourceStream("BWP.WinFormControl.Images." + png); if (this.InvokeRequired) { this.BeginInvoke(new Action(() => { picNetStatus.Image = Image.FromStream(s); picNetStatus.Refresh(); })); } else { picNetStatus.Image = Image.FromStream(s); picNetStatus.Refresh(); } laseConnection = newConnection; } catch (Exception e) { //LogUtil.Error(e.ToString()); } Thread.Sleep(1000); } } private void SyncLocalToMiddleDb() { while (true) { if (laseConnection) { this.BeginInvoke(new Action(() => { SegmentationWeightRecordRpc.GetInstance().SyncToServer(); })); } Thread.Sleep(1000); } } private void cbxBatch_SelectedIndexChanged(object sender, EventArgs e) { InitPlanGoodsNumber(); } private void InitPlanGoodsNumber() { if (cbxBatch.Text == "SegmentationWeight.DropDownSet_Detail") { return; } if (LoginRpcUtil.TestConnection(1000)) { var json = RpcFacade.Call("/MainSystem/B3ClientService/Rpcs/BillRpc/ProductTaskRpc/GetListByBatch", cbxBatch.Text); mProductTasks = JsonConvert.DeserializeObject>(json); XmlUtil.SerializerObjToFile(mProductTasks, mProductTasksFileName); } else { mProductTasks = XmlUtil.DeserializeFromFile>(mProductTasksFileName); } } private void InitCombox() { if (LoginRpcUtil.TestConnection(500)) { mDropDownSets = GetmDropDownSets(); XmlUtil.SerializerObjToFile(mDropDownSets, mDropDownSetsFileName); } else { mDropDownSets = XmlUtil.DeserializeFromFile(mDropDownSetsFileName); } var shop = mDropDownSets.Details.FirstOrDefault(x => x.Name == DropDownSets.车间); if (shop != null) { cbxWorkShop.DataSource = shop.Details; cbxWorkShop.DisplayMember = "Name"; cbxWorkShop.ValueMember = "ID"; } var unit = mDropDownSets.Details.FirstOrDefault(x => x.Name == DropDownSets.单元); if (unit != null) { cbxWorkUnit.DataSource = unit.Details; cbxWorkUnit.DisplayMember = "Name"; cbxWorkUnit.ValueMember = "Code"; } var batch = mDropDownSets.Details.FirstOrDefault(x => x.Name == DropDownSets.批次); if (batch != null) { cbxBatch.DataSource = batch.Details; cbxBatch.DisplayMember = "Name"; cbxBatch.ValueMember = "ID"; } } private DropDownSets GetmDropDownSets() { var sets = new DropDownSets(); var wrokUnitSet = GetWrokUnitSet(); var wrokShopSet = GetWrokShopSet(); var productBatchSet = GetProductBatchSet(); sets.Details.Add(wrokUnitSet); sets.Details.Add(wrokShopSet); sets.Details.Add(productBatchSet); return sets; } private DropDownSet GetProductBatchSet() { var json = RpcFacade.Call("/MainSystem/B3ClientService/Rpcs/BaseInfoRpc/GetProductBatchList"); var set = new DropDownSet(); set.Name = DropDownSets.批次; foreach (var detail in JsonConvert.DeserializeObject>(json)) { set.Details.Add(detail); } return set; } private DropDownSet GetWrokShopSet() { var json = RpcFacade.Call("/MainSystem/B3ClientService/Rpcs/BaseInfoRpc/GetWorkShopList"); var set = new DropDownSet(); set.Name = DropDownSets.车间; foreach (var detail in JsonConvert.DeserializeObject>(json)) { set.Details.Add(detail); } return set; } private DropDownSet GetWrokUnitSet() { var json = RpcFacade.Call("/MainSystem/B3ClientService/Rpcs/BaseInfoRpc/GetWorkUnitList"); var set = new DropDownSet(); set.Name = DropDownSets.单元; foreach (var detail in JsonConvert.DeserializeObject>(json)) { set.Details.Add(detail); } return set; } #region weightNeed void OpenSerialPort() { if (!_enableWeight) 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": case "IND231": _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(); } #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) { InitPlanGoodsNumber(); InitWeightRecords(); RefreshUi(); InitControl(); btnEnd.BackColor = SystemColors.Control; btnStart.BackColor = Color.Green; } private void InitWeightRecords() { mAllWeightRecords = GetAllWeightRecords(); } private BindingList GetAllWeightRecords() { var list = SegmentationWeightRecordRpc.GetInstance().GetTodayList(); var resList = new BindingList(); foreach (SegmentationWeightRecord record in list) { record.Index = resList.Count + 1; resList.Insert(0, record); } return resList; } private void InitControl() { mSetList = XmlUtil.DeserializeFromFile>(SegmentationWeightGoodsSetForm.SegmentationWeightGoodsSetFileName).Where(x => x.IsSelected).ToList(); 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; btn.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); btn.BackColor = SystemColors.Control; btn.Width = 100; btn.Height = 60; 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.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); btn.Click += BtnGoods_Click; btn.BackColor = SystemColors.Control; btn.Width = 140; btn.Height = 80; return btn; } //点击存货 private void BtnGoods_Click(object sender, EventArgs e) { if (!_alreadyStart) { MessageBox.Show("先点击开始按钮"); return; } var btn = sender as Button; btn.BackColor = Color.Green; Application.DoEvents(); var set = btn.Tag as SegmentationWeightGoodSet; // if (mWeightRecords.Count > 0) // { // var oldText = mWeightRecords.First().Goods_Name; // if (set.Goods_Name != oldText) // { // MessageBox.Show("跟上次不是同一个存货"); // return; // } // } lblGoodsName.Text = set.Goods_Name; lblGoodsSpec.Text = set.Goods_Spec; _selectGoodsID = set.Goods_ID; mIsNeedRefreshPlan = true;//todo 这里可以完善 //添加记录 var record = GetRecordBySet(set); var id = LocalDmoSession.Insert(record); record.ID = id; record.Index = mAllWeightRecords.Count + 1; mAllWeightRecords.Insert(0, record); mWeightRecords.Insert(0, record); RefreshUi(); if (_enablePrint) { PrintGoodsEntity(record); } btn.BackColor = SystemColors.Control; Application.DoEvents(); } void PrintGoodsEntity(SegmentationWeightRecord record) { var entity = CreatePrintEntity(record); #if DEBUG SegmentationWeightPrint.Print(entity); #endif #if !DEBUG SegmentationWeightPrint.Print5050(entity); #endif } PrintEntity CreatePrintEntity(SegmentationWeightRecord record) { var entity = new PrintEntity(); entity.AccountingUnit_Name = "青岛万福集团股份有限公司"; entity.Goods_Name = record.Goods_Name; entity.Date = DateTime.Today; entity.Checker = "001"; entity.StoreCondition = "0-4℃ 4日"; entity.Place = "青岛莱西市珠海路5号"; entity.TelNumber = "0532-88488888"; entity.BarCode = record.BarCode; entity._2DQRCode = string.Format(ButcherAppContext.Context.UrlConfig.OutAddress + "?code={0}&gid={1}", entity.BarCode, record.Goods_ID); entity.Weight = record.Weight.ToString("#0.##"); return entity; } void RefreshUi() { //改成定时任务从数据库中取 //lblNumber.Text = mWeightRecords.Count.ToString(); //lblWeight.Text = mWeightRecords.Sum(x => x.Weight).ToString(); if (mIsNeedRefreshPlan) { lblPlanWeight.Text = mProductTasks.Where(x => x.Goods_Name == lblGoodsName.Text).Sum(x => x.Number).ToString("#0.##"); lblPlanNumber.Text = mProductTasks.Where(x => x.Goods_Name == lblGoodsName.Text).Sum(x => x.SecondNumber).ToString("#0.##"); } if (mAllWeightRecords.Count < 1) { return; } uDataGridView1.DataSource = mAllWeightRecords; uDataGridView1.CurrentCell = null; } private long _selectGoodsID = 0; private void SyncAlreadyFromMiddleDb() { while (true) { if (!string.IsNullOrWhiteSpace(lblGoodsName.Text)) { if (this.IsHandleCreated) { this.BeginInvoke(new Action(() => { try { var res = RpcFacade.Call("/MainSystem/B3ClientService/Rpcs/BillRpc/SegmentationWeightRecordRpc/GetCountByNameAndBatch", _selectGoodsID, cbxBatch.Text); lblNumber.Text = res.Split(',')[0]; lblWeight.Text = res.Split(',')[1]; lblLeftNumber.Text = (GetDecimal(lblPlanNumber.Text) - GetDecimal(lblNumber.Text)).ToString(); lblLeftWeight.Text = (GetDecimal(lblPlanWeight.Text) - GetDecimal(lblWeight.Text)).ToString(); } catch (Exception e) { LogUtil.Error(e.ToString()); } })); } } Thread.Sleep(2000); } } decimal GetDecimal(string value) { if (value == "") { return 0m; } return decimal.Parse(value); } private SegmentationWeightRecord GetRecordBySet(SegmentationWeightGoodSet set) { var unitValue = cbxWorkUnit.SelectedValue.ToString(); if (string.IsNullOrWhiteSpace(unitValue)) { throw new Exception("请选择工作单元"); } var record = new SegmentationWeightRecord(); record.Goods_ID = set.Goods_ID; string liushuihao = GetLiuShuiHao(); record.BarCode = "A26091201" + DateTime.Today.ToString("yyyyMMdd") + cbxWorkUnit.SelectedValue + liushuihao; record.Goods_Name = set.Goods_Name; record.Goods_Spec = set.Goods_Spec; record.BiaoShi = cbxWorkUnit.Text; record.ProductBatch = cbxBatch.Text; var weight = Convert.ToDecimal(lblChengZhong.Text); record.Weight = weight; record.CardBarCode = ""; // return record; } private int globleLiuShuiHao = 0; private string GetLiuShuiHao() { if (globleLiuShuiHao == 0) { globleLiuShuiHao = SegmentationWeightRecordRpc.GetTodayTotalCount(DateTime.Today); } globleLiuShuiHao++; string indexCode = globleLiuShuiHao.ToString("D5"); return indexCode; } public string RoleName { get { return "分割称重"; } } public Form Generate() { return this; } private void btnWeightSet_Click(object sender, EventArgs e) { var form = new WeightSettingFrom(); form.ShowDialog(); } private bool _alreadyStart = false; private void btnStart_Click(object sender, EventArgs e) { _alreadyStart = true; btnStart.Enabled = false; btnEnd.Enabled = true; btnStart.BackColor = SystemColors.Control; btnEnd.BackColor = Color.ForestGreen; } private void btnEnd_Click(object sender, EventArgs e) { _alreadyStart = false; _selectGoodsID = 0; lblGoodsName.Text = ""; lblPlanWeight.Text = ""; lblPlanNumber.Text = ""; lblLeftNumber.Text = ""; lblLeftWeight.Text = ""; if (mWeightRecords.Count > 0) { var endBarcode = GetEndBarCode(); foreach (SegmentationWeightRecord record in mWeightRecords) { record.CardBarCode = endBarcode; LocalDmoSession.Update(record, "CardBarCode"); } PrintEnd(endBarcode); //清空记录 mWeightRecords.Clear(); } btnStart.Enabled = true; btnEnd.Enabled = false; btnEnd.BackColor = SystemColors.Control; btnStart.BackColor = Color.ForestGreen; } private void PrintEnd(string barcode) { var entity = new PrintEntity(); entity.Weight = mWeightRecords.Sum(x => x.Weight).ToString(); entity.Number = mWeightRecords.Count.ToString(); entity.BarCode = barcode; entity.AccountingUnit_Name = "青岛万福集团股份有限公司"; #if DEBUG SegmentationWeightPrint.PrintEnd(entity); #endif #if !DEBUG SegmentationWeightPrint.PrintEnd5050(entity); #endif } private string GetEndBarCode() { var barcode = "fgend" + cbxWorkUnit.SelectedValue + DateTime.Now.ToString("yyyyMMddHHmmss"); return barcode; } private bool _enableWeight = false; private void btnEnableWeight_Click(object sender, EventArgs e) { _enableWeight = !_enableWeight; if (_enableWeight) { btnEnableWeight.Text = "停止称重"; btnEnableWeight.BackColor = Color.ForestGreen; OpenSerialPort(); _mainProcessIsRun = true; ReadData(); } else { btnEnableWeight.Text = "开始称重"; btnEnableWeight.BackColor = SystemColors.Control; btnEnablePrint.UseVisualStyleBackColor = true; DisableWeight(); } } private bool _enablePrint = false; private void btnEnablePrint_Click(object sender, EventArgs e) { _enablePrint = !_enablePrint; if (_enablePrint) { btnEnablePrint.Text = "停止打码"; btnEnablePrint.BackColor = Color.ForestGreen; } else { btnEnablePrint.Text = "开始打码"; btnEnablePrint.BackColor = SystemColors.Control; btnEnablePrint.UseVisualStyleBackColor = true; } } private void btnRePrint_Click(object sender, EventArgs e) { if (_enablePrint) { var row = uDataGridView1.CurrentRow; if (row != null) { var record = row.DataBoundItem as SegmentationWeightRecord; if (record != null) { PrintGoodsEntity(record); uDataGridView1.CurrentCell = null; } } } } private void btnDelete_Click(object sender, EventArgs e) { if (MessageBox.Show("删除无法恢复,确定删除?", "删除", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { var row = uDataGridView1.CurrentRow; if (row != null) { var record = row.DataBoundItem as SegmentationWeightRecord; if (record != null) { LocalDmoSession.SaveDelete(record.ID); uDataGridView1.Rows.Remove(row); uDataGridView1.Refresh(); uDataGridView1.CurrentCell = null; mAllWeightRecords.Remove(record); mWeightRecords.Remove(record); } } } } private void btnSumbit_Click(object sender, EventArgs e) { try { btnSumbit.Enabled = false; Application.DoEvents(); if (LoginRpcUtil.TestConnection(1000)) { if (SegmentationWeightRecordRpc.GetInstance().IsSyncSucessed()) { var id=RpcFacade.Call("/MainSystem/B3ClientService/Rpcs/BillRpc/SegmentationWeightRecordRpc/CreateTodayB3OutputBill" ); if(id>0) { MessageBox.Show("同步完成,创建产出单:"+id); } else if (id == -1) { MessageBox.Show("同步完成"); } else { MessageBox.Show("同步失败"); } } else { MessageBox.Show("请等待数据同步完成"); } } else { MessageBox.Show("没有网络,请通知管理员"); } } catch (Exception exception) { LogUtil.Error(exception); MessageBox.Show(exception.ToString()); } finally { btnSumbit.Enabled = true; } } } }