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
|
|
|
|
private List<SegmentationWeightGoodSet> mSetList;
|
|
|
|
|
|
BindingList<SegmentationWeightRecord> mWeightRecords;
|
|
public SegmentationWeightForm()
|
|
{
|
|
InitializeComponent();
|
|
uDataGridView1.AutoGenerateColumns = false;
|
|
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<Tuple<decimal, bool>> 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<List<Tuple<decimal, bool>>> mWeighList = new ConcurrentQueue<List<Tuple<decimal, bool>>>();
|
|
|
|
static List<Tuple<decimal, bool>> _list = new List<Tuple<decimal, bool>>();
|
|
|
|
public static void Add(decimal value, bool isStatic)
|
|
{
|
|
if (value >= SegmentationWeightContext.Config.MinWeight && value <= SegmentationWeightContext.Config.MaxWeight)
|
|
{
|
|
_list.Add(new Tuple<decimal, bool>(value, isStatic));
|
|
}
|
|
else
|
|
{
|
|
if (_list.Count > 0)
|
|
{
|
|
mWeighList.Enqueue(_list);
|
|
_list = new List<Tuple<decimal, bool>>();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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<SegmentationWeightRecord>();//以后可能取数据库中没做完的,比如做着做着突然断点
|
|
RefreshUi();
|
|
InitControl();
|
|
}
|
|
|
|
|
|
private void InitControl()
|
|
{
|
|
mSetList = XmlUtil.DeserializeFromFile<List<SegmentationWeightGoodSet>>(SegmentationWeightGoodsSetForm.SegmentationWeightGoodsSetFileName).Where(x => x.IsSelected).ToList();
|
|
if (mSetList.Count < 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
flpClass.Controls.Clear();
|
|
foreach (IGrouping<string, SegmentationWeightGoodSet> 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.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.Click += BtnGoods_Click;
|
|
btn.Width = 100;
|
|
btn.Height = 60;
|
|
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;
|
|
}
|
|
|
|
private void btnWeightSet_Click(object sender, EventArgs e)
|
|
{
|
|
var form=new WeightSettingFrom();
|
|
form.ShowDialog();
|
|
}
|
|
}
|
|
}
|