电话订餐系统讲解(3)
下订单的详细设计:
该功能是本系统的最重要的部分。将做为详细设计中的重点来说明:
界面如下:
下订单的状态转换图:
本系统用到了来电显示盒,通过它来实现电脑与电话来电之间的数据传送。下面依次上状态图顺序详细介绍实现过程:
第一步,来电后捕捉电话号码
在主窗口加载的时候打开串行端口进行端口监听。实现方法如下:
声明相关变量:
//C#内置支持的端口类
private SerialPort Sp = new SerialPort();
//声明HandleInterfaceUpdataDelegate的委托
public delegate void HandleInterfaceUpdataDelegate(string text); //HandleInterfaceUpdataDelegate的对象
private HandleInterfaceUpdataDelegate interfaceUpdataHandle;
配置端口:
//实例化委托对象
interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(Ordering);
Sp.PortName = "COM4";//端口名称
Sp.BaudRate = 1200;//端口每秒位数
Sp.Parity = Parity.None;//优先级设置
Sp.StopBits = StopBits.One;//停止位设置
Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);//有数据来的回调函数
Sp.ReceivedBytesThreshold = 1;//数据来多少触动
回调函数:
private void Ordering(string text)
{
//得到来电显示号码进行处理
string newtext = text.Substring(4);
//传递来电显示号码并且弹出下订单窗口
frmOrderAdd frmorderadd = new frmOrderAdd(newtext);
frmorderadd.MdiParent = this;
frmorderadd.Show();
}
public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//得到来电显示信息
byte[] readBuffer = new byte[Sp.ReadBufferSize];
Sp.Read(readBuffer, 0, readBuffer.Length);
//传递并调用interfaceUpdataHandle类型委托即Ordering函数
this.Invoke(interfaceUpdataHandle, new string[] { Encoding.UTF8.GetString(readBuffer) });
}
第二步:对号码的判断
这时候下订单窗口已经弹出同时也传递来电号码至其中。我们要对该号码进行判断是否是新号码。主要是对tb_Phone与tb_Member的存在,判断是否有结果具体的SQL语句为:
select RealName,Address,MID from tb_Member where MID in (select MID from tb_Phone where Context='" + phone + "') and IsValid=1。
按照前面系统分层的设计:有依次的调用过程在此不重复。
声明Member业务逻辑对象:
private BMember bmember = new BMember();
对来电号码的判断:
/// <summary>
/// 对来电猫的号码进行处理
/// </summary>
public void BoolSet()
{
DataTable dt = bmember.GetMemByPhone(lbPhone.Text);
if (dt.Rows.Count == 0)
{
新电话号码
。。。。。。
}
else
{
已存在的电话号码
。。。。。。
}
}
第三步:新电话号码的处理以及对已存在电话号码的处理
设置一个全局变量判断是为新电话号码bool flag;
如果是新电话号码,设置flag为true。同时隐藏下拉列表(设计供多个客户使用一个电话的情况下进行选择操作)为什么这此只对flag进行设置即可呢?需求是要对该号码进行建立档案,即向tb_Member与tb_Phone中插入不完整的客户信息。但是考虑到如果是打错电话、或者与非订餐电话就这样的插入没什么意义。应该将等填完整信息添加订单时再插入这些客户信息。这样可以保证该电话为客户。
否则如果是已经存在的电话号码,设置flag为false.对得到的DataTable dt的数据行数进一步判断:
if (dt.Rows.Count == 1)
{
读取名客户字与地址显示在对应文本框中
隐藏下拉列表
}
else
{
读取名客户字与地址显示在对应文本框中
显示下拉列表并且绑定其他同一电话号码的客户名字与ID
}
第四步:选择或添写具体客户
这步主要是考虑各种可能不在我们上面的考虑范围内的情况,可以让用户灵活修改客户信息,举一例子说明问题:假如来电号码确实存在于我们的数据库中,但是不是数据库中对应的客户打来的,也就是说一客户用了别人的客户的电话打过来这时候就需要系统能够修改和选择。因此我们在客户姓名后面设计了打开按钮提供选择点击后弹出客户选择对话框,其实是调用了客户管理窗口(当然对该窗口进行适当动态修改)。如下图:
用户可以根据选择客户窗口中的各种便利查询选择客户。并且将值传递回订单添加窗口中。代码如下:
点击打开按钮的事件相关处理代码:
private void btChangeMeb_Click(object sender, EventArgs e)
{
frmMember frmmember = new frmMember(1,this);//特殊处理的构造函数
frmmember.Text = "选择客户";
frmmember.ControlBox = false;
frmmember.ShowDialog();
}
frmMember窗口中的相关代码:
private frmOrderAdd fadd = new frmOrderAdd();
private bool flag = false;//是否下订单
public frmMember(int i,frmOrderAdd fadda)
{
fadd = fadda;
InitializeComponent();
//界面调整
toolAdd.Visible = false;
toolDel.Visible = false;
toolUpdate.Visible = false;
toolRefresh.Visible = false;
Width = 400;
Height = 300;
dgvMember.Width = 395;
dgvMember.Height = 215;
ControlBox = false;
flag = true;//下订单
}
frmMember窗口GridView控件的行双击事件相关处理代码:
private void dgvMember_CellClick(object sender, DataGridViewCellEventArgs e)
{
//客户ID
int MID = (int)this.dgvMember[5, this.dgvMember.CurrentCell.RowIndex].Value;
//如果是下订单
if (flag)
{
//回调frmOrderAdd中的Update()方法,即改变下订单窗口(传递本窗口中选择客户的ID)
fadd.Update(MID);
//关闭当前窗口
this.Close();
}
}
frmOrderAdd中的Update方法相关代码:
public void Update(int MID)
{
flag=false;//不是新用户
mid = MID;
//从数据库中读取信息并且显示
txtName.Text = bmember.GetMemAddressPayTypeID(MID).Rows[0][2].ToString();
txtAddress.Text = bmember.GetMemAddressPayTypeID(MID).Rows[0][0].ToString();
if (bphone.GetPhones(MID).Rows.Count > 0)
{
txtPhone.Text = bphone.GetPhones(MID).Rows[0][1].ToString();
}
btChangeMeb.Text = "打开";
lbpaytypeid.Text = bmember.GetMemAddressPayTypeID(MID).Rows[0][1].ToString();
}
第五步:填写订餐信息等
这步主要是供接线员根据用户的要求填写,不得不说明下。根据需求在此进行了适当的简化,即将所有订餐类别按价格来分不按餐名而分。因为出现上面的界面设计。一个健壮的系统对用户的非法填写要进行验证。具体在填写过程中应该对填写快餐数量进行验证。也就是在文本框的文本改变事件中调用下面函数:代码如下:
/// <summary>
/// 判断数据字符是否为数字
/// </summary>
/// <param name="strCode">需要判断的字符串</param>
/// <returns></returns>
public static bool IsNumeric(string strCode)
{
if (strCode == null || strCode.Length == 0)
{
return false;
}
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] byteStr = ascii.GetBytes(strCode);
foreach (byte code in byteStr)
{
if (code < 48 || code > 57)
return false;
}
return true;
}
第六步:下订单保存
这是最后一步。将得到的信息插入到数据库中的表中。首先得对所有必须的信息进行验证。
然后根据flag进行判断,如果true,就是新客户那就得向数据库中的tb_Phone、 tb_Member表中插入相关数据以及向tb_Order中插入订单信息,否则只要向tb_Order中插入订单信息即可。主要是对业务逻辑层的方法调用。
这次讲解完毕,如对本次讲解有疑问联系qq:344927817(注明:博客园)
待续...