using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
using BO;
|
|
using BO.BarCodeScan;
|
|
using BO.BO.Dtos;
|
|
using BO.Utils;
|
|
using BO.Utils.BillRpc;
|
|
using BWP.WinFormControl.WeightDataFormat;
|
|
using TrunksIousOutInStore.LocalSyncBO;
|
|
using TrunksIousOutInStore.Rpc;
|
|
|
|
namespace TrunksIousOutInStore
|
|
{
|
|
public partial class TrunksIousOutInStoreForm : Form, IAfterLogin
|
|
{
|
|
|
|
private readonly string ClientGoodsSetApplyClient = "白条出入库";
|
|
public const string DATA_PATH = "LocalData/TrunksIousOutInStore";
|
|
|
|
// BardCodeHooK BarCode = new BardCodeHooK();
|
|
|
|
#region weightNeed
|
|
SerialPort weightPort;
|
|
private IDataFormat _dataFormat;
|
|
private Thread _inQueryThread;
|
|
private bool _mainProcessIsRun;
|
|
readonly StringBuilder _dataStrBuilder = new StringBuilder();
|
|
#endregion
|
|
|
|
|
|
public TrunksIousOutInStoreForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
gridUnCheck.AutoGenerateColumns = false;
|
|
gridChecked.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();
|
|
};
|
|
|
|
// BarCode.BarCodeEvent += new BardCodeHooK.BardCodeDeletegate(BarCode_BarCodeEvent);
|
|
|
|
if (!Directory.Exists(DATA_PATH))
|
|
{
|
|
Directory.CreateDirectory(DATA_PATH);
|
|
}
|
|
}
|
|
void BarCode_BarCodeEvent(BardCodeHooK.BarCodes barCode)
|
|
{
|
|
ShowInfo(barCode);
|
|
}
|
|
private delegate void ShowInfoDelegate(BardCodeHooK.BarCodes barCode);
|
|
|
|
private void ShowInfo(BardCodeHooK.BarCodes barCode)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.BeginInvoke(new ShowInfoDelegate(ShowInfo), new object[] { barCode });
|
|
}
|
|
else
|
|
{
|
|
if (barCode.IsValid)
|
|
{
|
|
// var code = UrlUtil.GetBarCode(barCode.BarCode.Trim());
|
|
// var goodsName = UrlUtil.GetGoodsName(barCode.BarCode);
|
|
var code = barCode.BarCode.Trim();
|
|
doInsertUnSubmit(code, "", null);
|
|
}
|
|
}
|
|
}
|
|
|
|
#region weightNeed
|
|
void OpenSerialPort()
|
|
{
|
|
if (enableWeight.Checked)
|
|
return;
|
|
if (TrunksIousOutInStoreContext.Config.RateSet == null)
|
|
throw new Exception("请先配置称相关信息");
|
|
|
|
weightPort.PortName = TrunksIousOutInStoreContext.Config.ComSet;
|
|
weightPort.BaudRate = TrunksIousOutInStoreContext.Config.RateSet.Value;
|
|
weightPort.DataBits = TrunksIousOutInStoreContext.Config.BitSet.Value;
|
|
weightPort.ReadBufferSize = 4096 * 100;
|
|
if (!string.IsNullOrEmpty(TrunksIousOutInStoreContext.Config.Format))
|
|
format = "{0:{format}}".Replace("{format}", TrunksIousOutInStoreContext.Config.Format);
|
|
|
|
switch (TrunksIousOutInStoreContext.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 (TrunksIousOutInStoreContext.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")
|
|
{
|
|
//AddWeightDetail(decimal.Parse(lblChengZhong.Text));
|
|
doInsertUnSubmit("", "", decimal.Parse(lblChengZhong.Text));
|
|
}
|
|
}));
|
|
}
|
|
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)));
|
|
//AddWeightDetail(decimal.Parse(string.Format(format, num)));
|
|
}
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
_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 >= TrunksIousOutInStoreContext.Config.MinWeight && value <= TrunksIousOutInStoreContext.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
|
|
|
|
|
|
|
|
static object _obj = new object();
|
|
private void doInsertUnSubmit(string barCode, string goodsName, decimal? weight)
|
|
{
|
|
lock (_obj)
|
|
{
|
|
var record = new TrunksIousOutInStoreRecord();
|
|
record.Goods_Name = goodsName;
|
|
var set = GetSelectedClientGoodsSet();
|
|
if (set != null)
|
|
{
|
|
record.Goods_Name = set.Goods_Name;
|
|
record.Goods_ID = set.Goods_ID;
|
|
}
|
|
record.Number = 1;
|
|
record.CarcassStatus = cbxBaiTiaoStatus.Text;
|
|
if (!string.IsNullOrWhiteSpace(barCode))
|
|
{//扫码
|
|
record.BarCode = barCode;
|
|
//找到条码为空但是重量不为空的
|
|
var fd = unSumbitList.FirstOrDefault(x => string.IsNullOrWhiteSpace(x.BarCode) && x.Weight.HasValue);
|
|
if (fd == null)
|
|
{
|
|
// record.ID = unSumbitList.Max(x => x.ID) + 1;
|
|
unSumbitList.Add(record);
|
|
}
|
|
else
|
|
{
|
|
//给条码赋值
|
|
fd.BarCode = barCode;
|
|
}
|
|
}
|
|
if (weight.HasValue)
|
|
{//称重
|
|
record.Weight = weight;
|
|
//找到称重为空条码不为空的
|
|
var fd = unSumbitList.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.BarCode) && x.Weight == null);
|
|
if (fd == null)
|
|
{
|
|
// record.ID = unSumbitList.Max(x => x.ID) + 1;
|
|
unSumbitList.Add(record);
|
|
}
|
|
else
|
|
{
|
|
//给条码赋值
|
|
fd.Weight = weight;
|
|
}
|
|
}
|
|
gridUnCheck.Refresh();
|
|
Application.DoEvents();
|
|
// BindUnCheckGrid();
|
|
}
|
|
|
|
// barCodequeue.Enqueue(barCode);
|
|
}
|
|
|
|
|
|
|
|
public string RoleName
|
|
{
|
|
get { return "胴体白条出入库"; }
|
|
}
|
|
public Form Generate()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string goodsSetFileName = Path.Combine(DATA_PATH, "TrunksIousOutInStoreClientGoodsSet.xml");
|
|
|
|
private List<TrunksIousOutInStoreClientGoodsSet> mLocaList;
|
|
|
|
void InitLocalList()
|
|
{
|
|
if (LoginRpcUtil.TestConnection())
|
|
{
|
|
mLocaList = ClientGoodsSetRpc.GetListByApplyClient(ClientGoodsSetApplyClient).Select(x => x.CreateChild<TrunksIousOutInStoreClientGoodsSet>()).ToList();
|
|
XmlUtil.SerializerObjToFile(mLocaList, goodsSetFileName);
|
|
}
|
|
else
|
|
{
|
|
mLocaList = XmlUtil.DeserializeFromFile<List<TrunksIousOutInStoreClientGoodsSet>>(goodsSetFileName);
|
|
}
|
|
|
|
}
|
|
|
|
private void TrunksIousOutInStoreForm_Load(object sender, EventArgs e)
|
|
{
|
|
// BarCode.Start();
|
|
|
|
InitLocalList();
|
|
|
|
InitGoodsControl();
|
|
|
|
GridUnCheckFocus();
|
|
}
|
|
|
|
private void InitGoodsControl()
|
|
{
|
|
flpClass.Controls.Clear();
|
|
foreach (IGrouping<string, TrunksIousOutInStoreClientGoodsSet> grouping in mLocaList.Where(x=>!string.IsNullOrWhiteSpace(x.Name)).GroupBy(x=>x.Name))
|
|
{
|
|
var btn = CreateClassButton(grouping.Key);
|
|
flpClass.Controls.Add(btn);
|
|
}
|
|
}
|
|
|
|
private Button CreateClassButton(string text)
|
|
{
|
|
var btn = new Button(){Text = text};
|
|
btn.Width = 100;
|
|
btn.Height = 60;
|
|
btn.Click += BtnClass_Click;
|
|
return btn;
|
|
}
|
|
|
|
private void BtnClass_Click(object sender, EventArgs e)
|
|
{
|
|
var btnClass = sender as Button;
|
|
flpGoods.Controls.Clear();
|
|
foreach (TrunksIousOutInStoreClientGoodsSet set in mLocaList.Where(x=>x.Name== btnClass.Text))
|
|
{
|
|
var btn = CreateGoodsSetButton(set);
|
|
flpGoods.Controls.Add(btn);
|
|
}
|
|
GridUnCheckFocus();
|
|
Application.DoEvents();
|
|
}
|
|
|
|
private Button CreateGoodsSetButton(TrunksIousOutInStoreClientGoodsSet set)
|
|
{
|
|
var btn = new Button();
|
|
btn.Text = set.Goods_Name;
|
|
btn.Tag = set;
|
|
btn.Width = 100;
|
|
btn.Height = 60;
|
|
btn.Click += BtnSet_Click;
|
|
return btn;
|
|
}
|
|
|
|
private void BtnSet_Click(object sender, EventArgs e)
|
|
{
|
|
var btn = sender as Button;
|
|
foreach (Button button in flpGoods.Controls)
|
|
{
|
|
if (button.Text == btn.Text)
|
|
{
|
|
if (button.BackColor == Color.Aqua)
|
|
{
|
|
button.BackColor = SystemColors.Control;
|
|
}
|
|
else
|
|
{
|
|
button.BackColor = Color.Aqua;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
button.BackColor = SystemColors.Control;
|
|
}
|
|
}
|
|
gridUnCheck.Focus();
|
|
Application.DoEvents();
|
|
}
|
|
|
|
TrunksIousOutInStoreClientGoodsSet GetSelectedClientGoodsSet()
|
|
{
|
|
foreach (Button button in flpGoods.Controls)
|
|
{
|
|
if (button.BackColor == Color.Aqua)
|
|
{
|
|
return button.Tag as TrunksIousOutInStoreClientGoodsSet;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void TrunksIousOutInStoreForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if (unSumbitList.Count > 0)
|
|
{
|
|
if (MessageBox.Show("待提交区域不为空,确定关闭?", "确定关闭", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) ==
|
|
DialogResult.OK)
|
|
{
|
|
e.Cancel = false;
|
|
}
|
|
else
|
|
{
|
|
e.Cancel = true;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
BindingList<TrunksIousOutInStoreRecord> unSumbitList = new BindingList<TrunksIousOutInStoreRecord>();
|
|
BindingList<TrunksIousOutInStoreRecord> sumbitedList = new BindingList<TrunksIousOutInStoreRecord>();
|
|
// ConcurrentQueue<string> barCodequeue=new ConcurrentQueue<string>();
|
|
private void timer1_Tick(object sender, EventArgs e)
|
|
{
|
|
timer1.Stop();
|
|
if (unSumbitList == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var canSubmitList = unSumbitList.Where(x => !string.IsNullOrWhiteSpace(x.BarCode) && x.Weight != null).ToList();
|
|
foreach (TrunksIousOutInStoreRecord record in canSubmitList)
|
|
{
|
|
|
|
LocalDmoSession.Insert(record);
|
|
unSumbitList.Remove(record);
|
|
sumbitedList.Insert(0, record);
|
|
}
|
|
|
|
BindUnCheckGrid();
|
|
BindCheckedGrid();
|
|
|
|
timer1.Start();
|
|
}
|
|
|
|
void BindUnCheckGrid()
|
|
{
|
|
gridUnCheck.DataSource = unSumbitList;
|
|
}
|
|
void BindCheckedGrid()
|
|
{
|
|
gridChecked.DataSource = sumbitedList;
|
|
}
|
|
|
|
|
|
private void btnWeightSet_Click(object sender, EventArgs e)
|
|
{
|
|
var f = new WeightSettingFrom();
|
|
|
|
if (f.ShowDialog() == DialogResult.OK)
|
|
{
|
|
enableWeight_Click(sender, e);
|
|
GridUnCheckFocus();
|
|
}
|
|
}
|
|
|
|
void GridUnCheckFocus()
|
|
{
|
|
gridUnCheck.Focus();
|
|
}
|
|
|
|
private void TrunksIousOutInStoreForm_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
// BarCode.Stop();
|
|
}
|
|
|
|
|
|
#region 检查网络畅通
|
|
private void timerChectNetStatus_Tick(object sender, EventArgs e)
|
|
{
|
|
timerChectNetStatus.Stop();
|
|
ChectConnectionStatus();
|
|
timerChectNetStatus.Start();
|
|
}
|
|
void ChectConnectionStatus()
|
|
{
|
|
if (LoginRpcUtil.TestConnection())
|
|
{
|
|
btnNetStatus.Text = "网络畅通";
|
|
btnNetStatus.BackColor = Color.Green;
|
|
}
|
|
else
|
|
{
|
|
btnNetStatus.Text = "网络不通";
|
|
btnNetStatus.BackColor = Color.Red;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 同步到中间服务器
|
|
//同步到
|
|
private void timerSyncToService_Tick(object sender, EventArgs e)
|
|
{
|
|
timerSyncToService.Stop();
|
|
if (LoginRpcUtil.TestConnection())
|
|
{
|
|
TrunksIousOutInStoreRecordRpc.GetInstance().SyncToServer();
|
|
}
|
|
timerSyncToService.Start();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 检查是否同步完成
|
|
|
|
//检查是否同步完成
|
|
private void timerCheckSyncSucessed_Tick(object sender, EventArgs e)
|
|
{
|
|
timerCheckSyncSucessed.Stop();
|
|
if (LoginRpcUtil.TestConnection())
|
|
{
|
|
if (TrunksIousOutInStoreRecordRpc.GetInstance().IsSyncSucessed())
|
|
{
|
|
btnSycnStatus.Text = "同步完成";
|
|
btnSycnStatus.BackColor = Color.Green;
|
|
}
|
|
else
|
|
{
|
|
btnSycnStatus.Text = "正在同步";
|
|
btnSycnStatus.BackColor = Color.Red;
|
|
}
|
|
}
|
|
timerCheckSyncSucessed.Start();
|
|
}
|
|
#endregion
|
|
|
|
private void btnCreateBill_Click(object sender, EventArgs e)
|
|
{
|
|
GridUnCheckFocus();
|
|
}
|
|
|
|
BwpBarCodes barCodes = new BwpBarCodes();
|
|
|
|
private void TrunksIousOutInStoreForm_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.KeyData == (Keys.ShiftKey | Keys.Shift))
|
|
{
|
|
return;
|
|
}
|
|
TimeSpan ts = DateTime.Now.Subtract(barCodes.Time);
|
|
var str = BwpBarCodeUtil.GetStringByKeyKeyEventArgs(e);
|
|
barCodes.StringBuilder.Append(str);
|
|
|
|
if (ts.TotalMilliseconds < 50)
|
|
{
|
|
if (e.KeyData == Keys.Enter && barCodes.BarCode.Length > 0)
|
|
{
|
|
//回车
|
|
barCodes.IsValid = true;
|
|
barCodes.StringBuilder.Remove(barCodes.StringBuilder.Length - 1, 1);
|
|
}
|
|
}
|
|
try
|
|
{
|
|
if (barCodes.IsValid)
|
|
{
|
|
|
|
|
|
// MessageBox.Show(barCodes.BarCode);
|
|
doInsertUnSubmit(barCodes.BarCode, "", null);
|
|
barCodes.StringBuilder = new StringBuilder();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
|
|
barCodes.IsValid = false; //最后一定要 设置barCode无效
|
|
barCodes.Time = DateTime.Now;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|