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<GradeAndWeight> list;
|
|
List<GradeAndWeight_Detail> details;
|
|
SerialPort weightPort;
|
|
int maxIndex = 0;
|
|
readonly ConcurrentQueue<GradeAndWeight_Detail> tempList = new ConcurrentQueue<GradeAndWeight_Detail>();
|
|
|
|
// readonly ConcurrentQueue<long> _detailQueue = new ConcurrentQueue<long>();
|
|
//readonly ConcurrentQueue<decimal> _weightQueue = new ConcurrentQueue<decimal>();
|
|
|
|
#region weightNeed
|
|
private IDataFormat _dataFormat;
|
|
private Thread _inQueryThread, _outQueryThread;
|
|
private bool _mainProcessIsRun;
|
|
readonly StringBuilder _dataStrBuilder = new StringBuilder();
|
|
readonly ConcurrentQueue<string> _dataQueue = new ConcurrentQueue<string>();
|
|
|
|
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;
|
|
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);
|
|
// }
|
|
//}
|
|
|
|
GradeAndWeight_Detail modifyDetail;
|
|
|
|
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 livestockTag = btn.Tag as CTuple<long, string, short>;
|
|
if (modifyDetail == null)
|
|
AddDetail(livestockTag);
|
|
else
|
|
{
|
|
if (modifyDetail.Technics != livestockTag.Item3)
|
|
{
|
|
MessageBox.Show("工艺选择错误!请重新选择");
|
|
return;
|
|
}
|
|
modifyDetail.Livestock_ID = livestockTag.Item1;
|
|
modifyDetail.Livestock_Name = livestockTag.Item2;
|
|
GradeAndWeightRpc.UpdateLivestock(modifyDetail.ID, modifyDetail.Livestock_ID, modifyDetail.Livestock_Name);
|
|
historyGrid.Refresh();
|
|
modifyDetail = null;
|
|
modifyPanel.Hide();
|
|
}
|
|
|
|
//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 => x.Order).OrderBy(x => x.Finish).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 = null;
|
|
if (details.Any())
|
|
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<DataGridViewRow> GetEnableTopTowRows()
|
|
{
|
|
var result = new List<DataGridViewRow>();
|
|
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.DataLength - 1)
|
|
{
|
|
_dataStrBuilder.Append(c);
|
|
_dataQueue.Enqueue(_dataStrBuilder.ToString());
|
|
_dataStrBuilder.Clear();
|
|
}
|
|
else if (_dataStrBuilder.Length != 0)
|
|
{
|
|
_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")
|
|
{
|
|
this.Invoke(new InvokeHandler(delegate()
|
|
{
|
|
lblChengZhong.Text = _displayValue;
|
|
//AddWeightDetail(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 (details == null)
|
|
{
|
|
MessageBox.Show("请先同步数据");
|
|
return;
|
|
}
|
|
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
|
|
|
|
static object _obj = new object();
|
|
|
|
void AddDetail(CTuple<long, string, short> livestock)
|
|
{
|
|
lock (_obj)
|
|
{
|
|
var selectRows = GetEnableTopTowRows();
|
|
if (selectRows.Count == 0)
|
|
throw new Exception("没有可定级的数据记录了");
|
|
// var livestock = (CTuple<long, string, short>)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;
|
|
|
|
|
|
GradeAndWeight_Detail first;
|
|
if (tempList.TryPeek(out first) && first.Livestock_ID == 0)
|
|
{
|
|
tempList.TryDequeue(out first);
|
|
first.OrderDetail_ID = currentRow.OrderDetail_ID;
|
|
first.Order = currentRow.Order;
|
|
first.Livestock_ID = livestock.Item1;
|
|
first.Livestock_Name = livestock.Item2;
|
|
first.Technics = livestock.Item3;
|
|
first.Technics_Name = livestock.Item3 == 0 ? "烫褪" : "毛剥";
|
|
GradeAndWeightRpc.InsertOrInsertDetail(first);
|
|
historyGrid.Refresh();
|
|
}
|
|
else//add
|
|
{
|
|
maxIndex++;
|
|
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.InsertOrInsertDetail(entity);
|
|
tempList.Enqueue(entity);
|
|
BindDetailGrid();
|
|
}
|
|
currentRow.Already = currentRow.Already + 1;
|
|
|
|
BindDataGrid();
|
|
}
|
|
}
|
|
|
|
void AddWeightDetail(decimal weight)
|
|
{
|
|
lock (_obj)
|
|
{
|
|
weight -= (GradeContext.Config.Discont ?? 0);
|
|
GradeAndWeight_Detail first;
|
|
if (tempList.TryPeek(out first) && first.Weight == null)
|
|
{
|
|
tempList.TryDequeue(out first);
|
|
first.Weight = weight;
|
|
GradeAndWeightRpc.InsertOrInsertDetail(first);
|
|
historyGrid.Refresh();
|
|
}
|
|
else//add
|
|
{
|
|
maxIndex++;
|
|
var entity = new GradeAndWeight_Detail();
|
|
entity.Index = maxIndex;
|
|
entity.Weight = weight;
|
|
entity.Time = DateTime.Now;
|
|
details.Insert(0, entity);
|
|
GradeAndWeightRpc.InsertOrInsertDetail(entity);
|
|
tempList.Enqueue(entity);
|
|
BindDetailGrid();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void cancelBtn_Click(object sender, EventArgs e)
|
|
{
|
|
modifyDetail = null;
|
|
modifyPanel.Hide();
|
|
}
|
|
|
|
private void historyGrid_CellClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
if (e.RowIndex < 0)
|
|
return;
|
|
modifyDetail = historyGrid.Rows[e.RowIndex].DataBoundItem as GradeAndWeight_Detail;
|
|
stateLabel.Text = string.Format("您正在修改序号为 {0} 的等级", modifyDetail.Index);
|
|
modifyPanel.Show();
|
|
}
|
|
}
|
|
}
|