您的位置:首页 > 其它

快餐刷卡消费之触摸屏实现(含关键源码)

2016-04-23 15:28 323 查看
本项目为连锁店餐饮系统。前台C#,服务器采用Java开发,oracle数据库;通过webservice实现前后台的交互,后台以提供服务的方式,供前端调用并进行数据库操作。

商家根据餐饮副食店实际情况提出了新的需求,希望能够通过在店内放置触摸屏的方式,使会员顾客能够以触摸屏的方式选择商品并放入自己的购物车,之后售货员只需要读取卡内的购物车信息即可刷卡消费,这样大大节约了顾客挑选商品的时间,使整个购物流程并行化程度提高。由于顾客消费的时间大多集中在早中晚,并行化会使店内的销售量显著提高。

经过一周的时间终于完成了模块的更新,下面我将分4个方面详细的描述整个流程,并附上关键部分源码,分享给大家共同学习。

1.功能模块介绍;2,触屏设置实现(前台、服务器、数据库);3,触屏显示实现;4,触屏结算实现

一 功能模块介绍:

展柜设置(包括4个子模块)

1.1 触屏设置(管理员操作)

本子模块包括4项功能:

——选择:根据门店编号mdbh从数据库消费记录表和物料表中获取外卖记录,显示在combox中;

——插入:管理员从combox中选取要显示的商品图片,获取该图片的绝对路径,以记录的方式插入到config.txt文本中,每个图片代表一条记录

——删除:删除TXT文档中对应的条目。

——保存:将当前Imagelistview中的商品图片信息保存成TXT文档,存储在项目的指定目录下。

1.2 触屏显示(顾客操作)

本模块中,自动加载“触屏设置”中保存的TXT文档,读取其中的记录并将对应的图片全屏显示;双击图片会进入商品细节页面,在本界面,顾客可以选择”加入购物车“或”返回“,本页面能够显示库存量,若库存量《0,点击返回后对应图片将显示售罄。

同时设置两个按钮“上一页”,“下一页”,通过点击可以实现翻页查看。

(注:顾客通过本显示屏可以看到本店内所有的商品信息,并有选择的加入到自己卡的购物车中)

1.3 触屏结算(售货员操作)

本模块包括3项功能:

——读卡:售货员点击“读卡”,系统将卡内的购物车信息显示在购物车栏中;

——修改:删除菜品:售货员可以对购物车中的商品调整数量或删除

——结算:对IC卡的购物车商品结算,同时删除数据库中对应的购物车信息,执行卡金额操作,并打印小票。

1.4 图片下载(管理员操作)

通过FTP的方式,管理员可以从指定的FTP目录中选择图片,加入本门店的图片库中,供展柜设置使用。

总体界面设计:

1.5 总体流程:

前台:主要是画界面,写webservice调用方法,逻辑实现;

服务器端:若无对应的服务,则注册webservice服务(1.在sun-jaxws.xml 中通过endpoint注册;2.在对应的服务中加入注解,@webservice和@HandlerChain和@webMethod,注意名字要和xml中对应;注册完服务之后,通过具体的方法执行Sql语句操作数据库,反馈到前台,显示。

当思路清晰、宏观设计之后,具体的实现就是搬砖的过程,我们只需要一步步的根据需求完成模块即可。Let’s go!

二 触屏设置

2.1界面设计:

2.2自动加载物料表,Combox显示

1.通过调用getYLData方法从数据库中获取物料数据存入List中

private void initYL(String lb)
{

物料编号.Visible = true;
ylComb.Visible = true;
ylAddBtn.Visible = true;
getYLData(lb); //设置物料表ylList

if (ylList != null)
{
foreach (DataBean bean in ylList)
{
//物料列表
this.ylComb.Items.Add(bean.GetValue("WL_WLBH") + "|" + bean.GetValue("WL_WLMC") + "|" + bean.GetValue("WL_3lMC") + "|" + bean.GetValue("WL_JLDW") + "|" + bean.GetValue("SL"));

}
}
}


2.通过webservice调取服务MaterialService中的getDataFromXSJL方法获取物料数据,存入ArrayList中。

private void getYLData(string ALMC)
{
ServiceDelegate serviceDelegate = ServiceDelegateFactory.Instance();
//ArrayList materialList = new ArrayList();
try
{
ylList = (ArrayList)serviceDelegate.CommonInvoke("MaterialService", "getDataFromXSJL", ALMC);

}
catch (Exception ex)
{
if (ex is WebServiceException)
{
if ((ex as WebServiceException).ExceptionType ==
EnumDefine.WebServiceException.ConnectException)
{
PopMessage.Error("EXC0009E", ConfigUtil.GetItemValue("ErrorMessageTitle"));
}
else
{
PopMessage.Error("EXC0006E", ConfigUtil.GetItemValue("ErrorMessageTitle"));
}
}
else
{
throw ex;
}
return;
}
if (serviceDelegate.MessageList != null)
{
ServiceMessageBean popMessage = (ServiceMessageBean)serviceDelegate.MessageList[0];

if (popMessage.Parameters != null)
{
PopMessage.Error(popMessage.MessageCode, ConfigUtil.GetItemValue("ErrorMessageTitle"), popMessage.Parameters);
}
else
{
PopMessage.Error(popMessage.MessageCode, ConfigUtil.GetItemValue("ErrorMessageTitle"));
}

serviceDelegate.MessageList.Clear();
}
}


3.服务器代码

MaterialService中的getDataFromXSJL方法:

public List getDataFromXSJL(String mdbh) throws Exception {
List<?> resultList = dao.selectDataFromKCDL(mdbh);
if (resultList == null || resultList.isEmpty()) {
messages.add(new ServiceMessage(CommonConst.RESULTNULL));
return null;
} else {
return resultList;
}
}

@Override
public List<?> selectDataFromKCDL(String mdbh) throws SysException {
StringBuffer sb = new StringBuffer();
List<Object> argsList = new ArrayList<Object>();

sb.append("select ");
sb.append(" WL_WLBH,WL_WLMC,WL_3LMC, WL_JLDW,sum(DXFJL_SL) AS SL");
sb.append(" from  ");
sb.append("   T_JCZL_WL left join T_KWGL_DXFJL on  ");
sb.append("   WL_WLBH=DXFJL_CPBH  AND  substr(DXFJL_XFLSH,0,?)=?");
sb.append(" where ");
sb.append("   WL_2lMC=?  ");
sb.append(" group by WL_WLBH,WL_WLMC,WL_3LMC, WL_JLDW ");
//		sb.append("   WL_WLMC ");

argsList.add(mdbh.length());
argsList.add(mdbh);
argsList.add("外卖");

AppLog.logSystemInfo(WlDao.class, "selectDataBy1LMC", sb.toString()
.replace('\'', '"'));
List<?> list = (List<?>) sqlRunner
.executeQuery(sb.toString(),argsList);
return WsCommon.listConvert(list, sb.toString());
}


2.3 插入和删除

操作和2.2类似.

2.4 保存

分析:声明configPic.txt配置文件和图片的存放位置,创建文件流和字节流,将2.2中插入的菜品所对应的图片的绝对路径存入txt文件中,然后将txt文件中保存的信息在触屏显示中读取。
private void saveBtn_Click(object sender, EventArgs e)
{
string filePath = Application.StartupPath + "/Pic/used/configPic.txt";
string imagePath = Application.StartupPath + "/Pic/";

if (dataGridView1.Rows.Count < 1)
return;

imageListView1.Items.Clear();
FileStream fs = new FileStream(filePath, FileMode.Create);
StreamWriter sw = new StreamWriter(fs);

foreach (DataGridViewRow row in dataGridView1.Rows)
{
sw.WriteLine(imagePath+row.Cells["WL_WLBH"].Value.ToString() + ".jpg");
}

sw.Flush();//保护硬盘
//关闭流
sw.Close();
fs.Close();
this.toolStripStatusLabel.Text = "保存成功!";
String[] fileLines = System.IO.File.ReadAllLines(filePath);
imageListView1.Items.AddRange(fileLines);//触屏显示
}

三 触屏显示

分析:1.显示txt中的图片信息2.增加双击事件,即双击图片可以查看其细节信息,并进入对应的窗体3.在商品细节窗体中可以把其“保存”进购物车,并返回。4.本界面显示库存余量,若<=0,点击返回后将自动将图片置换为售罄(通过字符串替换,修改config.txt文件中的内容)

3.1 按钮控制滚动条

//导入dll用来控制鼠标上下移动
[DllImport("user32.dll")]
static extern void mouse_event(int flags, int dX, int dY, int buttons, int extraInfo);
const int MOUSEEVENTF_WHEEL = 0x800;

private void btnDown_Click(object sender, EventArgs e)
{
this.imageListView1.Focus();
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, -300, 0);
}

private void btnUp_Click(object sender, EventArgs e)
{
this.imageListView1.Focus();
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, 300, 0);
}


3.2 “返回”按钮事件

private void rtn_Click(object sender, EventArgs e)
{
if (this.kc.Text == "0") {//判断当前的库存量
string filePath = Application.StartupPath + "/Pic/used/configPic.txt";//配置文本文件
string imagePath = Application.StartupPath + "/Pic/Out/" + _picId + "out.jpg";//Out文件夹存储售罄图片
string imagePathUsed = Application.StartupPath + "/Pic/used/" + _picId + ".jpg";//当前显示的图片存储的文件夹
string line;
//通过字节流操作文件
StreamReader sr1 = new StreamReader(filePath);
string s = sr1.ReadToEnd();
sr1.Close();

StreamReader sr = new StreamReader(filePath);
while ((line = sr.ReadLine()) != null)
{
if (line.Equals(imagePathUsed)) {
sr.Close();
StreamWriter sw = new StreamWriter(filePath);
sw.WriteLine(s.Replace(imagePathUsed, imagePath).Trim());
sw.Flush();
sw.Close();
break;
}
}
}
base.MoveToNextForm(typeof(ShowBoxMain));
this.Close();
}


四 触屏销售

4.1 模块展示:

分析:本模块设计的内容较多,主要包括1.读卡2.结算3.打印小票

4.2 读卡

分析:关键点:1. CardOperation和CardDbOperation读取卡号和卡内数据(具体读卡操作略过,如有需要可以私信博主)2.通过方法getDataByGWC(ickh);获取卡内的购物车数据3.绑定数据源到dgv,注意将dgv中列的NAME属性和DataPropertyName属性一一对应,否则绑定失败。

private void readBtn_Click(object sender, EventArgs e)
{
//点餐前检查是否有IC卡放置好
DataBean dataTable1 = null;
CardOperation co = new CardOperation();
CardDbOperation codb = new CardDbOperation();
string ickh = co.getICKH();
this.ickh_txb.Text = ickh;
if (ickh.Length < 2)
{
MessageBox.Show("请放好消费卡!");
return;
}
dataTable1 = codb.getICCard(ickh);
this.knye_txb.Text = dataTable1.GetValue("IC_CZYE").ToString();
///读卡之后,在购物车篮显示商品
///1.读取数据库getAllData返回map<key,value>
///2.将map显示到dgv上
getDataByGWC(ickh);
this.dinnerDetailDgv.DataSource = ServiceDelegate.ListToDataTable(resultList);
int i = 0;
foreach (DataGridViewRow row in dinnerDetailDgv.Rows)
{
DataGridViewRow dgr = dinnerDetailDgv.Rows[i];
dgr.Cells["IC_ICKH"].Value = dinnerDetailDgv.Rows[i].Cells["IC_ICKH"].Value.ToString().Trim();
i++;
}
RefreshTotal();
}
//获取门店订单
private void getDataByGWC(string ickh)
{
ServiceDelegate serviceDelegate = ServiceDelegateFactory.Instance();
try
{
resultList = (ArrayList)serviceDelegate.CommonInvoke("CardService", "GetCaseByICKH", ickh);
}
catch (Exception ex)
{
return;
}
if (resultList == null)
{
ServiceMessageBean popMessage = (ServiceMessageBean)serviceDelegate.MessageList[0];

if (popMessage.Parameters != null)
{
PopMessage.Error(popMessage.MessageCode, ConfigUtil.GetItemValue("ErrorMessageTitle"), popMessage.Parameters);
}
else
{
PopMessage.Error(popMessage.MessageCode, ConfigUtil.GetItemValue("ErrorMessageTitle"));
}

serviceDelegate.MessageList.Clear();
}

}


4.3 结算

///1.获取dgv上面的金额总数 ///2.操作卡内余额 ///3.删除该IC卡的GWC数据 ///4.打印小票,获取cgv上的数据

if (dinnerDetailDgv.Rows.Count <= 0)
{
MessageBox.Show("购物车中无商品!");
return;
}
//判断卡中金额是否足够,是则减掉金额,并作出卡和数据库的操作
CardOperation co = new CardOperation();
try
{

ickh = co.getICKH();

}
catch (Exception ex)
{
MessageBox.Show("读卡错误!");
return;
}

DataBean dataBean = new DataBean();
dataBean = getICCard(ickh);
if (dataBean == null)
{
MessageBox.Show("该卡不存在!");
return;
}

if (dataBean != null)
{
string dqzt = (string)dataBean.GetValue("IC_DQZT");
if (dqzt != "已开卡")
{
MessageBox.Show("该卡当前状态为" + dqzt + ",不可消费!");
return;
}
}
string a = (string)dataBean.GetValue("IC_CZYE").ToString();

double knye = NumberUtil.toDouble(dataBean.GetValue("IC_CZYE").ToString());

//取得datagridview数据
ids = new string[dinnerDetailDgv.Rows.Count];
names = new string[dinnerDetailDgv.Rows.Count];
counts = new string[dinnerDetailDgv.Rows.Count];
pricePerUnits = new string[dinnerDetailDgv.Rows.Count];
prices = new string[dinnerDetailDgv.Rows.Count];

string kplx = (string)dataBean.GetValue("IC_KPLX");
xfje = 0;

for (int i = 0; i < dinnerDetailDgv.Rows.Count; i++)
{  // 逐条遍历数据
ids[i] = (string)dinnerDetailDgv.Rows[i].Cells["GWC_CPBH"].Value;
names[i] = (string)dinnerDetailDgv.Rows[i].Cells["CPML_CPMC"].Value;
counts[i] = (string)dinnerDetailDgv.Rows[i].Cells["GWC_CPSL"].Value;
pricePerUnits[i] = (string)dinnerDetailDgv.Rows[i].Cells["CPML_HYJ"].Value;

if (kplx.Equals("会员卡"))
{
prices[i] = (string)dinnerDetailDgv.Rows[i].Cells["CPML_HYJ"].Value;
xfje += NumberUtil.toDouble((string)dinnerDetailDgv.Rows[i].Cells["CPML_HYJ"].Value) * NumberUtil.toDouble(counts[i]);

}
}

//判断余额是否足够
if (xfje > knye)
{
MessageBox.Show("消费金额:" + xfje + " 可用余额:" + knye + " 。IC卡余额不足,请充值!");
return;
}

//更改IC卡内的余额
dataBean.setValue("IC_CZYE", knye - xfje);
if (dataBean.GetValue("IC_BZ") == null)
dataBean.setValue("IC_BZ", "备注信息");

DataBean dataBean_MXFJL = new DataBean();
dataBean_MXFJL.ColumnName = new string[17] { "MXFJL_LSH", "MXFJL_MDLSH", "MXFJL_MDBH", "MXFJL_ICKH", "MXFJL_XSYBH", "MXFJL_XFSJ", "MXFJL_XFJE", "MXFJL_XFBTJE", "MXFJL_XFCZJE", "MXFJL_BTYE", "MXFJL_CZYE", "MXFJL_JEDW", "MXFJL_JSZT", "MXFJL_JSDH", "MXFJL_BZ", "MXFJL_JSFS", "MXFJL_XFLX" };
string czsj = CommonUtil.formatDateToStrDB(DateTime.Now);
dataBean_MXFJL.ColumnValue = new string[17] { userInfo.ShopId + czsj, "1001", userInfo.ShopId, ickh, userInfo.UserId, czsj, xfje.ToString(), "0", "0", "0", (knye - xfje).ToString(), "元", "未结算", "0", "0", "1", "0" };

ArrayList paramList = new ArrayList();
int n = dinnerDetailDgv.Rows.Count;
for (int i = 0; i < n; i++)
{
DataBean dataBean_detail = new DataBean();
dataBean_detail.ColumnName = new string[12] { "DXFJL_LSH", "DXFJL_XFLSH", "DXFJL_CPBH", "DXFJL_DJ", "DXFJL_JJDW", "DXFJL_SL", "DXFJL_JLDW", "DXFJL_CPMC", "DXFJL_JE", "DXFJL_CQ", "DXFJL_ZCDJ", "DXFJL_BZ" };
dataBean_detail.ColumnValue = new string[12] { i.ToString(), userInfo.ShopId + czsj, ids[i].ToString(), prices[i].ToString(), "元", counts[i].ToString(), "JLDW", names[i].ToString(), "0", "0", "0", "b" };
paramList.Add(dataBean_detail);

}

//  卡操作
//    je = co.CardSettlement(xfje);

//**更改远程数据库*****

//更新IC卡内余额,插入消费记录以及消费明细

ServiceDelegate serviceDelegate = ServiceDelegateFactory.Instance();
try
{ //
serviceDelegate.CommonInvoke("CardService", "cardConsume", new Object[3] { dataBean, dataBean_MXFJL, paramList });

// MessageBox.Show("员工发卡成功!");
}
catch (Exception ex)
{
if (ex is WebServiceException)
{
if ((ex as WebServiceException).ExceptionType ==
EnumDefine.WebServiceException.ConnectException)
{
// 警告提示:网络出现问题,Web服务超时或无法连接
PopMessage.Error("COM0002W", ConfigUtil.GetItemValue("MessageTitle"));
}
else
{
// 警告提示:连接Web服务时发生系统异常
PopMessage.Error("COM0003W", ConfigUtil.GetItemValue("MessageTitle"));
}
}
if (ex is WebServiceException)
{
if ((ex as WebServiceException).ExceptionType ==
EnumDefine.WebServiceException.ConnectException)
{
PopMessage.Error("EXC0009E", ConfigUtil.GetItemValue("ErrorMessageTitle"));
}
else
{
PopMessage.Error("EXC0010E", ConfigUtil.GetItemValue("ErrorMessageTitle"));
}
}
else
{
throw ex;
}

return;
}

if (serviceDelegate.MessageList != null)
{

ServiceMessageBean popMessage = (ServiceMessageBean)serviceDelegate.MessageList[0];

if (popMessage.Parameters != null)
{
PopMessage.Error(popMessage.MessageCode, ConfigUtil.GetItemValue("ErrorMessageTitle"), popMessage.Parameters);
}
else
{
PopMessage.Error(popMessage.MessageCode, ConfigUtil.GetItemValue("ErrorMessageTitle"));
}

serviceDelegate.MessageList.Clear();
}
double knye_new = knye - xfje;
MessageBox.Show("欢迎光临,您此次消费共计" + xfje + "元,卡内余额为" + knye_new + "元,已结算成功!");


服务器端cardService的cardConsume方法:

// 业务 : 消费
public void cardConsume(DataBean cardData, DataBean mxfjlData,
ArrayList<DataBean> xfjlDetailList) {

ICardDaoIF icDao = new ICardDao();
MxfjlDaoIF dao = new MxfjlDao();
DxfjlDaoIF xjjyDao = new DxfjlDao();
// KeHuDaoIF kehuDao = new KeHuDao();

int ic = 0;
int czjl = 0;
int xjjy = 0;
int kehu = 0;
try {
if (cardData != null) {
ic = icDao.updateICardData(cardData);
if (ic != 1) {
messages.add(new ServiceMessage(CommonConst.UPDATEFAIL));
return;
}
}
if (mxfjlData != null) {
czjl = dao.insertDatas(mxfjlData);
if (czjl != 1) {
messages.add(new ServiceMessage(CommonConst.INSERTFAIL));
return;
}
}
if (xfjlDetailList != null && !xfjlDetailList.isEmpty()) {
for (int i = 0; i < xfjlDetailList.size(); i++) {
xjjy = xjjyDao.insertDatas(xfjlDetailList.get(i));
if (xjjy != 1) {
messages.add(new ServiceMessage(CommonConst.INSERTFAIL));
return;
}
}
}
} catch (Exception e) {
messages.add(new ServiceMessage(CommonConst.SYSTEM_ANOMALY));
return;
}
}

@Override
public int insertICardData(DataBean param) throws SysException {
// 执行插入的Sql
StringBuffer sb = new StringBuffer();
// 放置参数的List
List<Object> argsList = new ArrayList<Object>();
// 根据业务组合生成Sql语句
sb.append("INSERT INTO T_KWGL_IC"
+ "(IC_ICKH,IC_WLBH,IC_MM,IC_CKRBH,IC_KPLX,IC_FKMDBH,IC_FKRBH,"
+ "IC_FKSJ,IC_BTYE,IC_CZYE,IC_JEDW,IC_DQZT,IC_BZ,IC_ZK)VALUES");

sb.append(" (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
argsList.add(param.getValue("IC_ICKH"));

argsList.add(param.getValue("IC_WLBH"));

argsList.add(param.getValue("IC_MM"));

argsList.add(param.getValue("IC_CKRBH"));

argsList.add(param.getValue("IC_KPLX"));

argsList.add(param.getValue("IC_FKMDBH"));

argsList.add(param.getValue("IC_FKRBH"));

argsList.add(param.getValue("IC_FKSJ"));

argsList.add(param.getValue("IC_BTYE"));

argsList.add(param.getValue("IC_CZYE"));

argsList.add(param.getValue("IC_JEDW"));

argsList.add(param.getValue("IC_DQZT"));

argsList.add(param.getValue("IC_BZ"));

argsList.add(param.getValue("IC_ZK"));

AppLog.logSystemInfo(ICardDao.class, "insertICardData", sb.toString()
.replace('\'', '"'));
return sqlRunner.executeUpdate(sb.toString(), argsList);
}


4.4 打印小票

分析:在结算之后,自动执行打印小票程序。主要是格式的编排,创建LPTControls对象,传入待打印字符串,操作小票机

//********打印小票***********
double spsl = 0;
LPTControls lpt = new LPTControls();
//string mycommanglines = System.IO.File.ReadAllText("./print.txt");//print.txt里写了条码机的命令
String printLines1 = "";
String printLines2 = "";
String printLines3 = "";

printLines1 = "\n                 门店\n";
printLines1 += "      " + userInfo.ShopId + "          " + userInfo.ShopName + "\n";
printLines1 += "-------------------------------------\n";
printLines1 += "    收 款 员: " + userInfo.UserId + "\n";
printLines1 += "    卡    号:  " + ickh.ToString() + "\n";
printLines1 += "-------------------------------------\n";
printLines1 += "    单号 :" + czsj + "\n";
printLines1 += "    品名       " + "   数量    " + "单价    " + "金额" + "\n";
printLines1 += "-------------------------------------\n";

for (int i = 0; i < dinnerDetailDgv.Rows.Count; i++)
{
double dj;
try
{
dj = NumberUtil.toDouble((string)dinnerDetailDgv.Rows[i].Cells["CPML_HYJ"].Value);

}
catch (Exception ex)
{
throw ex;
}
if (((string)dinnerDetailDgv.Rows[i].Cells["CPML_CPMC"].Value).Length > 6)
{
spsl += NumberUtil.toDouble((string)dinnerDetailDgv.Rows[i].Cells["GWC_CPSL"].Value);
int Slength = ((string)dinnerDetailDgv.Rows[i].Cells["CPML_CPMC"].Value).Length;
for (int j = 0; j < Slength; j = j + 4)
{
int addLength = j + 4;
if (addLength < Slength)
{
printLines2 += "  " + ((string)dinnerDetailDgv.Rows[i].Cells["CPML_CPMC"].Value).Substring(j, addLength) + "\n";
}
else
{
printLines2 += "  " + (((string)dinnerDetailDgv.Rows[i].Cells["CPML_CPMC"].Value).Substring(j, Slength - j)).PadRight(6, '\u3000');
}
}
printLines2 += "   " + ((string)(dinnerDetailDgv.Rows[i].Cells["GWC_CPSL"].Value)).PadRight(4, '\u3000') + (dj.ToString()).PadRight(8, ' ') + dinnerDetailDgv.Rows[i].Cells["CPML_HYJ"].Value + "\n";
}
else
{
spsl += NumberUtil.toDouble((string)dinnerDetailDgv.Rows[i].Cells["GWC_CPSL"].Value);
printLines2 += "  " + ((string)dinnerDetailDgv.Rows[i].Cells["CPML_CPMC"].Value).PadRight(6, '\u3000') + "   " + ((string)(dinnerDetailDgv.Rows[i].Cells["GWC_CPSL"].Value)).PadRight(4, '\u3000') + (dj.ToString()).PadRight(8, ' ') + (string)(dinnerDetailDgv.Rows[i].Cells["price"].Value) + "\n";
} // 其中 \u3000代表全角空格

//printLines2 += "  "+dinnerDetailDgv.Rows[i].Cells[1].Value + "   " + dinnerDetailDgv.Rows[i].Cells[2].Value + "    " + dj.ToString() + "    " + dinnerDetailDgv.Rows[i].Cells[3].Value + "\n";
}
printLines3 += "-------------------------------------\n";
printLines3 += "    数量合计:" + "  " + spsl.ToString() + "  件" + "\n";
printLines3 += "    金额合计:" + "  " + xfje.ToString() + "  元" + "\n";
printLines3 += "    卡内余额:" + "  " + knye_new.ToString() + "  元" + "\n";
printLines3 += "-------------------------------------\n";

printLines3 += "          期待您再次光临    \n";
printLines3 += "\n\n\n\n\n\n\n\n";

RawPrinterHelper.printLines1 = printLines1;
RawPrinterHelper.printLines2 = printLines2;
RawPrinterHelper.printLines3 = printLines3;
RawPrinterHelper.count = 0;
MessageBox.Show(printLines1 + printLines2 + printLines3);
lpt.Open();
lpt.Write(printLines1 + printLines2 + printLines3);
lpt.Close();
xfje = 0;
}
结算成功:

本博文为博主原创

转载请注明转自:blog.csdn.net/mengzhengyu1025
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: