公司根据客户要求定制了对接金蝶ERP后台的地磅系统,该系统能读取销售订单数据,通过地磅软件读取重量信息并处理,保存到金蝶系统单据中,实现自动称重入库。项目于2019年9月开发完成,历时10天,现已标准化,支持对接金蝶其他版本及其他ERP系统。实现方案选择了自行开发程序通过WebApi与金蝶通信,放弃了金蝶自带的地磅功能。系统功能包括读取订单、读磅、打印预览、保存数据等,并展示了部分核心代码。
一:项目概要
1.公司根据客户要求定制可对接金蝶ERP后台的地磅系统。
2.可以获取销售订单的基础数据,通过地磅软件读取相关重量信息并处理,保存到金蝶系统单据。(该单据可直接为入库单,实现自动称重入库,也可是其他单据,通过合并下推值入库单)。
3.数据处理逻辑根据客户实际需求进行开发。
4.项目开发于2019年09月,历时10天。
5.现已将项目代码及逻辑部分标准化,方便后期重复性使用。现系统可以支持对接金蝶其他版本及其他ERP系统。
二:实现方案选择
由于客户金蝶版本为金蝶Cloud,该版本自带地磅相关插件功能,故前期一直纠结于使用金蝶自带的地磅部分,还是开发单独的程序通过接口同金蝶进行通信。通过评估,最终选择了放弃使用金蝶自带地磅功能,选择了自行开发程序,通过WebApi和金蝶进行数据通信。
现将两种方案的优劣整理如下表格:
三:功能开发说明
3.1.数据流转概述
1.读取销售订单已审核单据,选单并回填到该地磅单据,方便将客户,订单号等信息传输到下游单据。
2.填写必要信息后,即可进行读磅操作。
3.读磅完成后即可进行打印预览及打印操作。
4.打印操作后,即可进行保存操作,保存的数据会提交到金蝶后台对应单据中。
3.2.效果展示
打印的图片部分地方已模糊处理
四:核心代码
由于代码实在太占用地方,所以此处主要分享两个个人认为比较重要的两个部分,第一个
首先是用于winform同WebApi交互的类
/// <summary>
/// 调用API接口类
/// </summary>
public static class HttpRequest
{
//调用接口返回内容
public static string GetFunction(string Url,string Method)
{
//string serviceAddress = "http://localhost/WebApi/api/OrderInfo/GetOrderInfo"; //示例接口网址
string serviceAddress = Url;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = Method;
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return retString;
}
}
其次是读磅操作部分核心代码
//根据当前串口对象,来判断操作
if (comm.IsOpen)
{
//丢弃缓冲区数据
comm.DiscardInBuffer();
//打开时点击,则关闭串口
comm.Close();
this.Invoke((EventHandler)(delegate
{
double Bx = 0.00; //毛重
double Mz = 0.00; //皮重
double KZ = 0.00; //克重
this.txShow.AppendText(str.Trim().Replace(" ", "") .Replace("SS", "稳定").Replace("SD", "不稳定"));
//将字符串显示并转到最后
txLength.Text = str.Trim().Replace(" ", "").Length.ToString();
//地磅显示赋值 毛重
if (this.tbBX.Text.ToString().Trim() != null && this.tbBX.Text.ToString().Trim() != "")
{
Bx = Convert.ToDouble(this.tbBX.Text.ToString().Trim());
}
//皮重赋值
if (this.tbMZ.Text.ToString().Trim() != null && this.tbMZ.Text.ToString().Trim() != "")
{
Mz = Convert.ToDouble(this.tbMZ.Text.ToString().Trim());
}
//克重赋值
this.tbJZ.Text = (Bx - Mz).ToString();
this.btnPrintView.Enabled = true;
this.btnPrint.Enabled = true;
}));
}
else //继续读磅
{
if (tbMC.Text.ToString().Trim() == "" || tbMC.Text.ToString().Trim() == null)
{
MessageBox.Show("未获取到米长,请输入");
} else if (tbJY.Text.ToString().Trim() == "" || tbJY.Text.ToString().Trim() == null) {
MessageBox.Show("未获取到检验人员,请输入");
}
else
{
this.Invoke((EventHandler)(delegate
{
try
{
if (received_count >= 800)
{
Clear();
Reset();
}
//关闭时点击,则设置好端口,波特率后打开
comm.PortName = comboPortName.Text;
comm.BaudRate = int.Parse(comboBaudrate.Text);
comm.Open();
this.btnPrintView.Enabled = false;
this.btnPrint.Enabled = false;
}
catch (Exception ex)
{
//捕获到异常信息,创建一个新的comm对象,之前的不能用了。
comm = new SerialPort();
//现实异常信息给客户。
MessageBox.Show(ex.Message);
}
}));
}
五:总结与反思
1. 首先做项目前一定要充分的考虑到项目的整个过程。充分讨论需求,不然只会来来回回的浪费时间
2. 涉及到大量的读写,异步多线程。