Browse Source

完成外卖的收银小票打印功能

zhangyang 6 years ago
parent
commit
7ee131c31c

BIN
bin/Win32/Debug/zhipuzi_pos_windows/zhipuzi_pos_windows.exe


+ 11 - 2
lewaimai_dispatch/helper/CLewaimaiString.h

@@ -2,8 +2,7 @@
 
 #include <codecvt>
 #include <iostream>
-
-using namespace std;
+#include <sstream>
 
 class CLewaimaiString
 {
@@ -83,5 +82,15 @@ public:
 	{
 		return UnicodeToUTF8(ANSIToUnicode(str));
 	}
+
+	static std::string DoubleToString(const double value, unsigned int precisionAfterPoint)
+	{
+		char str[256];
+
+		std::string pre = "%." + to_string(precisionAfterPoint) + "f";
+		sprintf(str, pre.c_str(), value);
+		string result = str;
+		return result;
+	}
 };
 

+ 33 - 5
lewaimai_dispatch/order/CWaimaiOrder.cpp

@@ -1,4 +1,4 @@
-#include "../pch/pch.h"
+#include "../pch/pch.h"
 #include "CWaimaiOrder.h"
 
 CWaimaiOrder::CWaimaiOrder()
@@ -10,7 +10,7 @@ CWaimaiOrder::~CWaimaiOrder()
 {
 }
 
-//通过订单ID,获取订单详情
+//通过订单ID,获取订单详情
 void CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 {
 	std::map<string, string> params;
@@ -21,7 +21,7 @@ void CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 	bool ret = CZhipuziHttpClient::RequestOld("/waimaiorder/getorderdetail", params, response);
 	if (!ret)
 	{
-		LOG_INFO("网络请求出错");
+		LOG_INFO("缃戠粶璇锋眰鍑洪敊");
 	}
 
 	rapidjson::Document document;
@@ -45,7 +45,7 @@ void CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 			LOG_INFO("response failed! message:" << document["errmsg"].GetString());
 		}
 		{
-			//获得数据成功
+			//鑾峰緱鏁版嵁鎴愬姛
 			rapidjson::Value& data = document["data"];
 
 			m_order_id = data["id"].GetString();
@@ -122,7 +122,7 @@ void CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 			m_invoice_type = data["invoice_type"].GetString();
 			m_tax_payer_id = data["tax_payer_id"].GetString();
 
-			//开始保存订单详情
+			//开始保存订单详情
 			rapidjson::Value& v_rows = data["order_item"];
 
 			for (rapidjson::SizeType i = 0; i < v_rows.Size(); ++i)
@@ -144,6 +144,34 @@ void CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 
 				m_order_items.push_back(newItem);
 			}
+
+			//寮€濮嬩繚瀛橀�璁鹃€夐」
+			v_rows = data["order_field"];
+
+			for (rapidjson::SizeType i = 0; i < v_rows.Size(); ++i)
+			{
+				rapidjson::Value& v_row_i = v_rows[i];
+
+				CWaimaiOrderField newItem;
+				newItem.name = v_row_i["name"].GetString();
+				newItem.value = v_row_i["value"].GetString();
+
+				m_order_field.push_back(newItem);
+			}
+
+			//寮€濮嬩繚瀛樺�鍊兼湇鍔¤垂
+			v_rows = data["addservice"];
+
+			for (rapidjson::SizeType i = 0; i < v_rows.Size(); ++i)
+			{
+				rapidjson::Value& v_row_i = v_rows[i];
+
+				CWaimaiOrderField newItem;
+				newItem.name = v_row_i["name"].GetString();
+				newItem.value = v_row_i["value"].GetString();
+
+				m_addservie.push_back(newItem);
+			}
 		}
 	}
 }

+ 2 - 1
lewaimai_dispatch/order/CWaimaiOrder.h

@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
 
 #include <string>
 #include <vector>
@@ -113,5 +113,6 @@ public:
 
 	std::vector<CWaimaiOrderItem> m_order_items;
 	std::vector<CWaimaiOrderField> m_order_field;
+	std::vector<CWaimaiOrderField> m_addservie;
 };
 

+ 1 - 1
lewaimai_dispatch/pch/pch.h

@@ -36,7 +36,7 @@
 #include <queue>
 #include <map>
 #include <algorithm>
-
+#include <limits>
 #include <thread>
 #include <chrono>
 #include <mutex>

+ 549 - 63
lewaimai_dispatch/tool/CPosPrinter.cpp

@@ -1,4 +1,4 @@
-#include "../pch/pch.h"
+#include "../pch/pch.h"
 #include "CPosPrinter.h"
 
 #include <winioctl.h>
@@ -16,20 +16,20 @@ CPosPrinter::~CPosPrinter()
 
 bool CPosPrinter::Init()
 {
-    //遍历USB设备,找到POS打印机路径
-    //设备路径
+    //遍历USB设备,找到POS打印机路径
+    //璁惧�璺�緞
     TCHAR * szDevicePath[MAX_DEVICE];
-    //设置中文字符
+    //璁剧疆涓�枃瀛楃�
     setlocale(LC_CTYPE, "chs");
     TCHAR* Port = NULL;
 
-    //分配需要的空间
+    //鍒嗛厤闇€瑕佺殑绌洪棿
     for(int i = 0; i < MAX_DEVICE; i++)
     {
         szDevicePath[i] = new TCHAR[256];
     }
 
-    //取设备路径
+    //取设备路径
     int nDevice = GetDevicePath((LPGUID)&USB_GUID, szDevicePath);
     int i = 0;
 
@@ -46,7 +46,7 @@ bool CPosPrinter::Init()
 
     if(m_hPort == INVALID_HANDLE_VALUE)
     {
-        // 打开端口失败
+        // 鎵撳紑绔�彛澶辫触
         return false;
     }
 
@@ -56,26 +56,276 @@ bool CPosPrinter::Init()
 void CPosPrinter::PrintWaimaiOrder(CWaimaiOrder& order)
 {
     POS_Reset();
-    POS_SetMotionUnit(180, 180);
 
-	string shop_name = "#" + order.m_restaurant_number + "   " + CLewaimaiString::UTF8ToANSI(order.m_shop_name);
-    POS_S_TextOut(shop_name);
+    string shop_name = "#" + order.m_restaurant_number + "  " + CLewaimaiString::UTF8ToANSI(order.m_shop_name);
+    POS_TextOut(shop_name, true);
     POS_FeedLine();
 
+    POS_FeedLine();
+
+	if (order.m_is_selftake == "1")
+	{
+		POS_TextOut("鍒板簵鑷�彇璁㈠崟", false, 1);
+		POS_FeedLine();
+
+		POS_FeedLine();
+
+		POS_TextOut("鍙栭�鍙凤細" + CLewaimaiString::UTF8ToANSI(order.m_take_food_code), true, 1);
+		POS_FeedLine();
+	}
+	else
+	{
+		POS_TextOut("澶栧崠璁㈠崟", false, 1);
+		POS_FeedLine();
+	}
+
+    POS_FeedLine();
+
+    if(order.m_is_selftake == "1")
+    {
+        //自取订单,打印自取信息
+
+    }
+
+    //璁㈠崟鏉ユ簮
+    string from_type = "订单来源:" + CLewaimaiString::UTF8ToANSI(order.m_from_type);
+    POS_TextOut(from_type);
+    POS_FeedLine();
+
+    //订单号
+    string order_no = "璁㈠崟鍙凤細" + CLewaimaiString::UTF8ToANSI(order.m_order_no);
+    POS_TextOut(order_no);
+    POS_FeedLine();
+
+    //濮撳悕
+	if (order.m_is_selftake != "1")
+	{
+		string name = "姓名:" + CLewaimaiString::UTF8ToANSI(order.m_customer_name);
+		POS_TextOut(name);
+		POS_FeedLine();
+	}
+
+    //鐢佃瘽
+    string phone = "电话:" + CLewaimaiString::UTF8ToANSI(order.m_phone);
+    POS_TextOut(phone);
+    POS_FeedLine();
+
+    //鍦板潃
+	if (order.m_is_selftake != "1")
+	{
+		string address = "地址:" + CLewaimaiString::UTF8ToANSI(order.m_address);
+		POS_TextOut(address);
+		POS_FeedLine();
+	}
+
+	//棰勮�閫夐」
+	if (order.m_order_field.size() > 1)
+	{
+		for (std::vector<CWaimaiOrderField>::iterator it = order.m_order_field.begin(); it != order.m_order_field.end() - 1; it++)
+		{
+			string order_field = CLewaimaiString::UTF8ToANSI((*it).name) + ":" + CLewaimaiString::UTF8ToANSI((*it).value);
+			POS_TextOut(order_field, false, 0);
+			POS_FeedLine();
+		}
+	}
+
+    //涓嬪崟鏃堕棿
+    string order_date = "下单时间:" + CLewaimaiString::UTF8ToANSI(order.m_order_date);
+    POS_TextOut(order_date);
+    POS_FeedLine();
+
+	//配送时间
+	if (order.m_is_selftake == "1")
+	{
+		string date = "自取时间:" + CLewaimaiString::UTF8ToANSI(order.m_delivery_date);
+		POS_TextOut(date);
+		POS_FeedLine();
+	}
+	else
+	{
+		string date = "閰嶉€佹椂闂达細" + CLewaimaiString::UTF8ToANSI(order.m_delivery_date);
+		POS_TextOut(date);
+		POS_FeedLine();
+	}
+
+    //准备开始打印商品详情
+    string lines = "--------------------------------";
+    POS_TextOut(lines);
+    POS_FeedLine();
+
+    //鍟嗗搧鏍囬�
+    POS_TextOut("鍟嗗搧              鍗曚环 鏁伴噺 閲戦�");
+    POS_FeedLine();
+
+    //鍟嗗搧鍐呭�
+    for(std::vector<CWaimaiOrderItem>::iterator it = order.m_order_items.begin(); it != order.m_order_items.end(); it++)
+    {
+        std::string food_name = (*it).m_food_name;
+        std::string food_price = (*it).m_item_price;
+        std::string quantity = (*it).m_quantity;
+
+        //璁$畻鎬讳环
+        double item_price = atof(food_price.c_str()) * atof(quantity.c_str());
+        std::string food_total_price = CLewaimaiString::DoubleToString(item_price, 2);
+
+		food_name = CLewaimaiString::UTF8ToANSI(food_name);
+
+        //先输出商品名字
+		std::vector<string> m_names = HandleFoodname(food_name);
+
+		std::string firstLine = m_names[0];
+		std::string priceShow = HandleFoodItemPrice(food_price);
+		std::string quantityShow = HandleFoodQuantity(quantity);
+		std::string priceTotalShow = HandleFoodTotalPrice(food_total_price);
+
+		std::string firstLineShow = firstLine + priceShow + quantityShow + priceTotalShow;
+
+
+        POS_TextOut(firstLineShow, false, 0);
+        POS_FeedLine();
+
+		for (std::vector<string>::iterator it = m_names.begin() + 1; it != m_names.end(); it++)
+		{
+			POS_TextOut((*it), false, 0);
+			POS_FeedLine();
+		}
+    }
+
+	//判断是否有备注
+	if (order.m_memo.length() > 0)
+	{
+		POS_FeedLine();
+		string address = "顾客备注:" + CLewaimaiString::UTF8ToANSI(order.m_memo);
+		POS_TextOut(address, false, 0);
+		POS_FeedLine();
+	}
+
+	//缁撴潫鍟嗗搧璇︽儏鎵撳嵃
+	POS_TextOut(lines);
 	POS_FeedLine();
+
+	//寮€濮嬫墦鍗板叾浠栫殑璐圭敤
+	bool is_other_money = false;
+
+	if (order.m_delivery > 0)
+	{
+		string delivery = "配送费:" + CLewaimaiString::DoubleToString((double)order.m_delivery, 2);
+		POS_TextOut(delivery, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	if (order.m_is_dabao == "1")
+	{
+		string dabao = "鎵撳寘璐癸細" + CLewaimaiString::UTF8ToANSI(order.m_dabao_money);
+		POS_TextOut(dabao, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	//寮€濮嬫樉绀哄�鍊兼湇鍔¤垂
+	if (order.m_addservie.size() > 0)
+	{
+		for (std::vector<CWaimaiOrderField>::iterator it = order.m_addservie.begin(); it != order.m_addservie.end(); it++)
+		{
+			string addservice = CLewaimaiString::UTF8ToANSI((*it).name) + ":" + CLewaimaiString::DoubleToString((double)atof((*it).value.c_str()), 2);
+			POS_TextOut(addservice, false, 0);
+			POS_FeedLine();
+
+			is_other_money = true;
+		}
+
+		is_other_money = true;
+	}
+
+	if (order.m_discount < 10)
+	{
+		string discount = "打折:" + CLewaimaiString::DoubleToString((double)order.m_discount, 2) + "折";
+		POS_TextOut(discount, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	if (order.m_is_member_discount == "1")
+	{
+		string member_discount = "会员优惠:-" + order.m_member_discount;
+		POS_TextOut(member_discount, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	if (order.m_is_firstcut == "1")
+	{
+		string firstcut = "首单优惠:-" + order.m_firstcut_value;
+		POS_TextOut(firstcut, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	//婊″噺
+	string::size_type position = order.m_promotion.find(":");
+	if (position != order.m_promotion.npos)
+	{
+		string promotion_value;
+		promotion_value.assign(order.m_promotion, position + 1);
+
+		string coupon = "满减优惠:-" + CLewaimaiString::DoubleToString((double)(atof(promotion_value.c_str())), 2);
+		POS_TextOut(coupon, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	if (order.m_coupon> 0)
+	{
+		string coupon = "浼樻儬鍒革細-" + CLewaimaiString::DoubleToString((double)order.m_coupon, 2);
+		POS_TextOut(coupon, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	if (atof(order.m_goods_coupon_value.c_str()) > 0.0001)
+	{
+		string coupon = "鍟嗗搧鍒革細-" + order.m_goods_coupon_value;
+		POS_TextOut(coupon, false, 0);
+		POS_FeedLine();
+
+		is_other_money = true;
+	}
+
+	if (is_other_money)
+	{
+		POS_TextOut(lines);
+		POS_FeedLine();
+	}
+
+	//鏈€鍚庢樉绀烘€讳环
+	POS_TextOut("鎬昏�锛氾骏" + CLewaimaiString::DoubleToString(order.m_price, 2), false, 2);
+	POS_FeedLine();
+
+	//鏄剧ず浠樻�鏂瑰紡
+	POS_TextOut("支付方式:" + CLewaimaiString::UTF8ToANSI(order.m_pay_type), false, 2);
 	POS_FeedLine();
-   
+
+    POS_FeedLine();
+
     POS_CutPaper();
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////
-//获取CreateFile的USB端口号
+//获取CreateFile的USB端口号
 ////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-// 根据GUID获得设备路径
-// lpGuid: GUID指针
-// pszDevicePath: 设备路径指针的指针,用于返回找到的路径
-// 返回: 成功得到的设备路径个数,可能不止1个
+// 鏍规嵁GUID鑾峰緱璁惧�璺�緞
+// lpGuid: GUID鎸囬拡
+// pszDevicePath: 设备路径指针的指针,用于返回找到的路径
+// 返回: 成功得到的设备路径个数,可能不止1个
 int CPosPrinter::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
 {
     HDEVINFO hDevInfoSet;
@@ -85,37 +335,37 @@ int CPosPrinter::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
     int nCount;
     int nTotle;
     BOOL bResult;
-    wstring strUSBPrint = TEXT("USB 打印支持");
-    // 取得一个该GUID相关的设备信息集句柄
+    wstring strUSBPrint = TEXT("USB 鎵撳嵃鏀�寔");
+    // 鍙栧緱涓€涓��GUID鐩稿叧鐨勮�澶囦俊鎭�泦鍙ユ焺
     hDevInfoSet = ::SetupDiGetClassDevs(lpGuid,     // class GUID
-                                        NULL,                    // 无关键字
-                                        NULL,                    // 不指定父窗口句柄
-                                        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    // 目前存在的设备
+                                        NULL,                    // 鏃犲叧閿�瓧
+                                        NULL,                    // 涓嶆寚瀹氱埗绐楀彛鍙ユ焺
+                                        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    // 目前存在的设备
 
-    // 失败...
+    // 澶辫触...
     if(hDevInfoSet == INVALID_HANDLE_VALUE)
     {
         printf("failed \r\n");
         return 0;
     }
 
-    // 申请设备接口数据空间
+    // 鐢宠�璁惧�鎺ュ彛鏁版嵁绌洪棿
     pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
     pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
     nTotle = -1;
     nCount = 0;
     bResult = TRUE;
 
-    // 设备序号=0,1,2... 逐一测试设备接口,到失败为止
+    // 璁惧�搴忓彿=0,1,2... 閫愪竴娴嬭瘯璁惧�鎺ュ彛锛屽埌澶辫触涓烘�
     while(bResult)
     {
         nTotle++;
         spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-        // 枚举符合该GUID的设备接口
+        // 枚举符合该GUID的设备接口
         bResult = ::SetupDiEnumDeviceInfo(
-                      hDevInfoSet,     // 设备信息集句柄
-                      (ULONG)nTotle,   // 设备信息集里的设备序号
-                      &spDevInfoData);        // 设备接口信息
+                      hDevInfoSet,     // 设备信息集句柄
+                      (ULONG)nTotle,   // 设备信息集里的设备序号
+                      &spDevInfoData);        // 璁惧�鎺ュ彛淇℃伅
 
         if(bResult)
         {
@@ -139,7 +389,7 @@ int CPosPrinter::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
 
             _tprintf(_T("buf = %s \r\n"), buf);
 
-            //是否是要找的设备类型
+            //鏄�惁鏄��鎵剧殑璁惧�绫诲瀷
             if(_tcscmp(buf, strUSBPrint.c_str()) != 0)
             {
                 continue;
@@ -147,30 +397,30 @@ int CPosPrinter::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
 
             _tprintf(_T("OK\r\n"));
             ifData.cbSize = sizeof(ifData);
-            // 枚舉符合該GUID的設備接口
+            // 枚舉符合該GUID的設備接口
             bResult = ::SetupDiEnumDeviceInterfaces(
-                          hDevInfoSet,     // 設備信息集句柄
-                          NULL,            // 不需額外的設備描述
+                          hDevInfoSet,     // 設備信息集句柄
+                          NULL,            // 不需額外的設備描述
                           lpGuid,          // GUID
-                          (ULONG)nTotle,   // 設備信息集里的設備序號
-                          &ifData);        // 設備接口信息
+                          (ULONG)nTotle,   // 設備信息集里的設備序號
+                          &ifData);        // 瑷�倷鎺ュ彛淇℃伅
 
             if(bResult)
             {
-                // 取得该设备接口的细节(设备路径)
+                // 鍙栧緱璇ヨ�澶囨帴鍙g殑缁嗚妭(璁惧�璺�緞)
                 bResult = SetupDiGetInterfaceDeviceDetail(
-                              hDevInfoSet,    // 设备信息集句柄
-                              &ifData,        // 设备接口信息
-                              pDetail,        // 设备接口细节(设备路径)
-                              INTERFACE_DETAIL_SIZE,    // 输出缓冲区大小
-                              NULL,           // 不需计算输出缓冲区大小(直接用设定值)
-                              NULL);          // 不需额外的设备描述
+                              hDevInfoSet,    // 设备信息集句柄
+                              &ifData,        // 璁惧�鎺ュ彛淇℃伅
+                              pDetail,        // 璁惧�鎺ュ彛缁嗚妭(璁惧�璺�緞)
+                              INTERFACE_DETAIL_SIZE,    // 输出缓冲区大小
+                              NULL,           // 不需计算输出缓冲区大小(直接用设定值)
+                              NULL);          // 不需额外的设备描述
 
                 if(bResult)
                 {
-                    // 复制设备路径到输出缓冲区
+                    // 澶嶅埗璁惧�璺�緞鍒拌緭鍑虹紦鍐插尯
                     ::_tcscpy_s(pszDevicePath[nCount], 256, pDetail->DevicePath);
-                    // 调整计数值
+                    // 调整计数值
                     nCount++;
                     _tprintf(_T("Cnt = %d,pDetail->DevicePath =%s\r\n"), nCount, pDetail->DevicePath);
                 }
@@ -178,17 +428,17 @@ int CPosPrinter::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
         }
     }
 
-    // 释放设备接口数据空间
+    // 閲婃斁璁惧�鎺ュ彛鏁版嵁绌洪棿
     ::GlobalFree(pDetail);
-    // 关闭设备信息集句柄
+    // 关闭设备信息集句柄
     ::SetupDiDestroyDeviceInfoList(hDevInfoSet);
     return nCount;
 }
 
-int CPosPrinter::WriteData(string meg)
+int CPosPrinter::WriteData(string msg)
 {
     DWORD dwWrite;
-    return WriteFile(m_hPort, meg.c_str(), (DWORD)meg.length(), &dwWrite, NULL);
+    return WriteFile(m_hPort, msg.c_str(), (DWORD)msg.length(), &dwWrite, NULL);
 }
 
 int CPosPrinter::WriteBuf(char *buf, int len)
@@ -199,17 +449,22 @@ int CPosPrinter::WriteBuf(char *buf, int len)
 
 int CPosPrinter::POS_Reset(void)
 {
-    string s;
-    s = "\x1B\x40";
-    WriteData(s);
+    char s[2] = {0x1B, 0x40};
+    WriteBuf(s, 2);
     return 0;
 }
 
 int CPosPrinter::POS_FeedLine(void)
 {
-    string s;
-    s = "\x0A";
-    WriteData(s);
+    char s[1] = {0x0A};
+    WriteBuf(s, 1);
+    return 0;
+}
+
+int CPosPrinter::POS_Feed(void)
+{
+    char s[3] = { 0x1B, 0x4A, 0x00 };
+    WriteBuf(s, 3);
     return 0;
 }
 
@@ -223,23 +478,90 @@ int CPosPrinter::POS_SetMotionUnit(int x, int y)
     return 0;
 }
 
-int CPosPrinter::POS_S_TextOut(string &abc)
+int CPosPrinter::POS_SET_MOVE_X()
 {
-    string s;
-    char SetAbsPos[4] = { 0x1B, 0x24, 0x46, 0x00 };
-    WriteBuf(SetAbsPos, 4);
-    char SelctFontType[3] = { 0x1B, 0x4D, 0x03 };
-    WriteBuf(SelctFontType, 3);
-    char SelctOutMode[3] = { 0x1D, 0x21, 0x00 };
-    WriteBuf(SelctOutMode, 3);
+    char s2[6] = { 0x1B, 0x44, 0x0C, 0x0E, 0x17, 0x00};
+    WriteBuf(s2, 6);
+    return 0;
+}
+
+int CPosPrinter::POS_MOVE_X()
+{
+    char s[1] = { 0x09 };
+    WriteBuf(s, 1);
+    return 0;
+}
+
+int CPosPrinter::POS_SET_ABS_X(int x, int y)
+{
+    char cx = (char)(x);
+    char cy = (char)(y);
+
+    char s1[4] = { 0x1B, 0x24, cx, cy };
+    WriteBuf(s1, 4);
+    return 0;
+}
+
+int CPosPrinter::POS_SET_PRINT_AREA(int x, int y)
+{
+    char cx = (char)(x);
+    char cy = (char)(y);
+
+    char s1[4] = { 0x1D, 0x57, cx, cy };
+    WriteBuf(s1, 4);
+    return 0;
+}
+
+/*
+ *align_type:0 左对齐 1 居中对齐 2右对齐
+ **/
+int CPosPrinter::POS_TextOut(string abc, bool is_double, int align_type)
+{
+    if(is_double)
+    {
+        char s1[3] = { 0x1B, 0x21, 0x30 };
+        WriteBuf(s1, 3);
+
+        char s2[3] = { 0x1C, 0x21, 0x0c };
+        WriteBuf(s2, 3);
+    }
+    else
+    {
+        char s1[3] = { 0x1B, 0x21, 0x00 };
+        WriteBuf(s1, 3);
+
+        char s2[3] = { 0x1C, 0x57, 0x00 };
+        WriteBuf(s2, 3);
+    }
+
+    if(align_type == 0)
+    {
+        char s1[3] = { 0x1B, 0x61, 0x00 };
+        WriteBuf(s1, 3);
+    }
+    else if(align_type == 1)
+    {
+        char s1[3] = { 0x1B, 0x61, 0x01 };
+        WriteBuf(s1, 3);
+    }
+    else if(align_type == 2)
+    {
+        char s1[3] = { 0x1B, 0x61, 0x02 };
+        WriteBuf(s1, 3);
+    }
+    else
+    {
+
+    }
+
     WriteData(abc);
     return 0;
 }
 
 int CPosPrinter::POS_CutPaper()
 {
-    char CutPaperMode[4] = { 0x1D, 0x56, 0x41, 0x00 };
-    WriteBuf(CutPaperMode, 4);
+    char s[4] = { 0x1D, 0x56, 0x41, 0x00 };
+    WriteBuf(s, 4);
     return 0;
 }
 
@@ -254,4 +576,168 @@ int CPosPrinter::POS_OutQRCode()
     WriteBuf(QRCode2, 16);
     WriteBuf(QRCode3, 8);
     return 0;
+}
+
+void CPosPrinter::CalWord(string s, int& nHanzi, int& nZimu)
+{
+    nHanzi = 0;
+    nZimu = 0;
+
+    const char* buffer = s.c_str();
+
+    while(*buffer++ != '\0')
+    {
+        if(!(*buffer >= 0 && *buffer <= 127))
+        {
+            //姹夊瓧
+            buffer++;
+
+            nHanzi++;
+        }
+        else
+        {
+            //瀛楁瘝
+            nZimu++;
+        }
+    }
+}
+
+std::vector<std::string>CPosPrinter::HandleFoodname(std::string oldname)
+{
+    std::vector<std::string> newnameArray;
+
+    int nHanzi, nZimu;
+
+    CalWord(oldname, nHanzi, nZimu);
+
+    int nWidth = nHanzi * 2 + nZimu;
+
+    if(nWidth <= 15)
+    {
+		//对于nWidth补空格
+		for (int i = 0; i < 15 - nWidth; i++)
+		{
+			oldname += " ";
+		}
+
+        newnameArray.push_back(oldname);
+
+        return newnameArray;
+    }
+
+    //瀹藉害澶т簬15鐨勬儏鍐碉紝濡傛灉瓒呰繃浜嗭紝灏辫�杩涜�鎹㈣�鎴�彇
+	const char* s = oldname.c_str();
+	
+	int nTmp = 0;
+	int nTotal = 0;
+	while (*s++ != '\0')
+	{
+		nTmp++;
+		nTotal++;
+
+		if (!(*(s) >= 0 && *(s) <= 127))
+		{
+			//汉字的情况
+			s++;
+
+			nTmp++;
+			nTotal++;
+		}
+
+		if (nTmp == 15)
+		{
+			//这里开始要换行了
+			string newnameItem;
+			newnameItem.assign(oldname, nTotal - nTmp, nTmp);
+
+			newnameArray.push_back(newnameItem);
+
+			nTmp = 0;
+		}
+		else if (nTmp == 14)
+		{
+			//濡傛灉鏄��14涓�簡锛屽垽鏂�笅涓€涓�槸涓嶆槸涓�枃锛屽�鏋滄槸鐨勮瘽涔熻�鎹㈣�
+			if (!(*(s + 1) >= 0 && *(s + 1) <= 127))
+			{
+				//下一个是中文,也要换行了,补齐一个空格
+				string newnameItem;
+				newnameItem.assign(oldname, nTotal - nTmp, nTmp);
+				newnameItem += " ";
+
+				newnameArray.push_back(newnameItem);
+
+				nTmp = 0;
+			}
+		}
+	}
+
+	if (nTmp > 0)
+	{
+		//处理分隔后的最后一行
+		string newnameItem;
+		newnameItem.assign(oldname, nTotal - nTmp, nTmp);
+
+		for (int i = 0; i < 15 - nTmp; i++)
+		{
+			newnameItem += " ";
+		}
+
+		newnameArray.push_back(newnameItem);
+	}
+
+	return newnameArray;
+}
+
+std::string CPosPrinter::HandleFoodItemPrice(std::string oldprice)
+{
+	double price = atof(oldprice.c_str());
+
+	if (price < 10.00)
+	{
+		//单位数
+		return "   " + oldprice;
+	}
+	else if (price > 9.99 && price < 100.00)
+	{
+		//双位数
+		return "  " + oldprice;
+	}
+	else
+	{
+		return " " + oldprice;
+	}
+}
+
+std::string CPosPrinter::HandleFoodQuantity(std::string oldquantity)
+{
+	int n = atoi(oldquantity.c_str());
+
+	if (n < 10)
+	{
+		return "  " + oldquantity;
+	}
+	else
+	{
+		return " " + oldquantity;
+	}
+}
+
+std::string CPosPrinter::HandleFoodTotalPrice(std::string oldprice)
+{
+	double price = atof(oldprice.c_str());
+
+	if (price < 10.00)
+	{
+		//单位数
+		return "   " + oldprice;
+	}
+	else if (price > 9.99 && price < 100.00)
+	{
+		//双位数
+		return "  " + oldprice;
+	}
+	else
+	{
+		return " " + oldprice;
+	}
 }

+ 21 - 5
lewaimai_dispatch/tool/CPosPrinter.h

@@ -1,15 +1,15 @@
-#pragma once
+#pragma once
 
 #include "../pch/pch.h"
 #include "../order/CWaimaiOrder.h"
 
-//SetupDiGetInterfaceDeviceDetail所需要的输出长度,定义足够大
+//SetupDiGetInterfaceDeviceDetail鎵€闇€瑕佺殑杈撳嚭闀垮害锛屽畾涔夎冻澶熷ぇ
 #define INTERFACE_DETAIL_SIZE	1024
 
-//设备数量上限,假设16台上限
+//设备数量上限,假设16台上限
 #define MAX_DEVICE 16
 
-//USB类的GUID
+//USB绫荤殑GUID
 const GUID USB_GUID = {0xa5dcbf10, 0x6530, 0x11d2, {0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed}};
 
 class CPosPrinter
@@ -28,12 +28,28 @@ private:
 
 	int POS_Reset(void);
 	int POS_FeedLine(void);
+	int POS_Feed(void);
 	int POS_SetMotionUnit(int x, int y);
-	int POS_S_TextOut(string &abc);
+
+	//璁剧疆妯�悜璺虫牸浣嶇疆
+	int POS_SET_MOVE_X();
+	int POS_MOVE_X();
+	int POS_SET_ABS_X(int x, int y);
+	int POS_SET_PRINT_AREA(int x, int y);
+
+	int POS_TextOut(string abc, bool is_double = false, int align_type = 0);
+
 	int POS_CutPaper();
 	int POS_OutQRCode();
 
+	//字符空格计算的辅助函数
+	void CalWord(string s,  int& nHanzi, int& nZimu);
 
+	//对名字进行换行处理
+	std::vector<std::string> HandleFoodname(std::string oldname);
+	std::string HandleFoodItemPrice(std::string oldprice);
+	std::string HandleFoodQuantity(std::string oldquantity);
+	std::string HandleFoodTotalPrice(std::string oldprice);
 private:
 	HANDLE m_hPort = NULL;
 };

+ 143 - 100
lewaimai_dispatch/wnd/OrderListUI.h

@@ -1,115 +1,158 @@
 #pragma once
 
-inline double CalculateDelay(double state) {
-	return pow(state, 2);
+inline double CalculateDelay(double state)
+{
+    return pow(state, 2);
 }
 
 class OrderListUI : public CTileLayoutUI
 {
 public:
-	enum { SCROLL_TIMERID = 10 };
+    enum { SCROLL_TIMERID = 10 };
 
-	OrderListUI() : m_uButtonState(0), m_dwDelayDeltaY(0), m_dwDelayNum(0), m_dwDelayLeft(0)
-	{
-		SetItemSize(CSize(1000, 200));
-	}
+    OrderListUI() : m_uButtonState(0), m_dwDelayDeltaY(0), m_dwDelayNum(0), m_dwDelayLeft(0)
+    {
+        SetItemSize(CSize(1000, 200));
+    }
 
-	//刷新
-	void Refresh();
+    //刷新
+    void Refresh();
 
-	void DoEvent(TEventUI& event)
-	{
-		if (!IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND) {
-			if (m_pParent != NULL) m_pParent->DoEvent(event);
-			else CTileLayoutUI::DoEvent(event);
-			return;
-		}
+    void DoEvent(TEventUI& event)
+    {
+        if(!IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND)
+        {
+            if(m_pParent != NULL)
+            {
+                m_pParent->DoEvent(event);
+            }
+            else
+            {
+                CTileLayoutUI::DoEvent(event);
+            }
+            return;
+        }
 
-		if (event.Type == UIEVENT_TIMER && event.wParam == SCROLL_TIMERID)
-		{
-			if ((m_uButtonState & UISTATE_CAPTURED) != 0) {
-				POINT pt = m_pManager->GetMousePos();
-				LONG cy = (pt.y - m_ptLastMouse.y);
-				m_ptLastMouse = pt;
-				SIZE sz = GetScrollPos();
-				sz.cy -= cy;
-				SetScrollPos(sz);
-				return;
-			}
-			else if (m_dwDelayLeft > 0) {
-				--m_dwDelayLeft;
-				SIZE sz = GetScrollPos();
-				LONG lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY);
-				if ((lDeltaY > 0 && sz.cy != 0) || (lDeltaY < 0 && sz.cy != GetScrollRange().cy)) {
-					sz.cy -= lDeltaY;
-					SetScrollPos(sz);
-					return;
-				}
-			}
-			m_dwDelayDeltaY = 0;
-			m_dwDelayNum = 0;
-			m_dwDelayLeft = 0;
-			m_pManager->KillTimer(this, SCROLL_TIMERID);
-			return;
-		}
-		if (event.Type == UIEVENT_BUTTONDOWN && IsEnabled())
-		{
-			m_uButtonState |= UISTATE_CAPTURED;
-			m_ptLastMouse = event.ptMouse;
-			m_dwDelayDeltaY = 0;
-			m_dwDelayNum = 0;
-			m_dwDelayLeft = 0;
-			::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));
-			m_pManager->SetTimer(this, SCROLL_TIMERID, 50U);
-			return;
-		}
-		if (event.Type == UIEVENT_BUTTONUP)
-		{
-			if ((m_uButtonState & UISTATE_CAPTURED) != 0) {
-				m_uButtonState &= ~UISTATE_CAPTURED;
-				::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
-				if (m_ptLastMouse.y != event.ptMouse.y) {
-					m_dwDelayDeltaY = (event.ptMouse.y - m_ptLastMouse.y);
-					if (m_dwDelayDeltaY > 120) m_dwDelayDeltaY = 120;
-					else if (m_dwDelayDeltaY < -120) m_dwDelayDeltaY = -120;
-					m_dwDelayNum = (DWORD)sqrt((double)abs(m_dwDelayDeltaY)) * 5;
-					m_dwDelayLeft = m_dwDelayNum;
-				}
-				else
-					m_pManager->KillTimer(this, SCROLL_TIMERID);
-			}
-			return;
-		}
-		if (event.Type == UIEVENT_SCROLLWHEEL)
-		{
-			LONG lDeltaY = 0;
-			if (m_dwDelayNum > 0) lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY);
-			switch (LOWORD(event.wParam)) {
-			case SB_LINEUP:
-				if (m_dwDelayDeltaY >= 0) m_dwDelayDeltaY = lDeltaY + 8;
-				else m_dwDelayDeltaY = lDeltaY + 12;
-				break;
-			case SB_LINEDOWN:
-				if (m_dwDelayDeltaY <= 0) m_dwDelayDeltaY = lDeltaY - 8;
-				else m_dwDelayDeltaY = lDeltaY - 12;
-				break;
-			}
-			if (m_dwDelayDeltaY > 100) m_dwDelayDeltaY = 100;
-			else if (m_dwDelayDeltaY < -100) m_dwDelayDeltaY = -100;
-			m_dwDelayNum = (DWORD)sqrt((double)abs(m_dwDelayDeltaY)) * 5;
-			m_dwDelayLeft = m_dwDelayNum;
-			m_pManager->SetTimer(this, SCROLL_TIMERID, 50U);
-			return;
-		}
-		CTileLayoutUI::DoEvent(event);
-	}
+        if(event.Type == UIEVENT_TIMER && event.wParam == SCROLL_TIMERID)
+        {
+            if((m_uButtonState & UISTATE_CAPTURED) != 0)
+            {
+                POINT pt = m_pManager->GetMousePos();
+                LONG cy = (pt.y - m_ptLastMouse.y);
+                m_ptLastMouse = pt;
+                SIZE sz = GetScrollPos();
+                sz.cy -= cy;
+                SetScrollPos(sz);
+                return;
+            }
+            else if(m_dwDelayLeft > 0)
+            {
+                --m_dwDelayLeft;
+                SIZE sz = GetScrollPos();
+                LONG lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY);
+                if((lDeltaY > 0 && sz.cy != 0) || (lDeltaY < 0 && sz.cy != GetScrollRange().cy))
+                {
+                    sz.cy -= lDeltaY;
+                    SetScrollPos(sz);
+                    return;
+                }
+            }
+            m_dwDelayDeltaY = 0;
+            m_dwDelayNum = 0;
+            m_dwDelayLeft = 0;
+            m_pManager->KillTimer(this, SCROLL_TIMERID);
+            return;
+        }
+        if(event.Type == UIEVENT_BUTTONDOWN && IsEnabled())
+        {
+            m_uButtonState |= UISTATE_CAPTURED;
+            m_ptLastMouse = event.ptMouse;
+            m_dwDelayDeltaY = 0;
+            m_dwDelayNum = 0;
+            m_dwDelayLeft = 0;
+            ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));
+            m_pManager->SetTimer(this, SCROLL_TIMERID, 50U);
+            return;
+        }
+        if(event.Type == UIEVENT_BUTTONUP)
+        {
+            if((m_uButtonState & UISTATE_CAPTURED) != 0)
+            {
+                m_uButtonState &= ~UISTATE_CAPTURED;
+                ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
+                if(m_ptLastMouse.y != event.ptMouse.y)
+                {
+                    m_dwDelayDeltaY = (event.ptMouse.y - m_ptLastMouse.y);
+                    if(m_dwDelayDeltaY > 120)
+                    {
+                        m_dwDelayDeltaY = 120;
+                    }
+                    else if(m_dwDelayDeltaY < -120)
+                    {
+                        m_dwDelayDeltaY = -120;
+                    }
+                    m_dwDelayNum = (DWORD)sqrt((double)abs(m_dwDelayDeltaY)) * 5;
+                    m_dwDelayLeft = m_dwDelayNum;
+                }
+                else
+                {
+                    m_pManager->KillTimer(this, SCROLL_TIMERID);
+                }
+            }
+            return;
+        }
+        if(event.Type == UIEVENT_SCROLLWHEEL)
+        {
+            LONG lDeltaY = 0;
+            if(m_dwDelayNum > 0)
+            {
+                lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY);
+            }
+            switch(LOWORD(event.wParam))
+            {
+            case SB_LINEUP:
+                if(m_dwDelayDeltaY >= 0)
+                {
+                    m_dwDelayDeltaY = lDeltaY + 8;
+                }
+                else
+                {
+                    m_dwDelayDeltaY = lDeltaY + 12;
+                }
+                break;
+            case SB_LINEDOWN:
+                if(m_dwDelayDeltaY <= 0)
+                {
+                    m_dwDelayDeltaY = lDeltaY - 8;
+                }
+                else
+                {
+                    m_dwDelayDeltaY = lDeltaY - 12;
+                }
+                break;
+            }
+            if(m_dwDelayDeltaY > 100)
+            {
+                m_dwDelayDeltaY = 100;
+            }
+            else if(m_dwDelayDeltaY < -100)
+            {
+                m_dwDelayDeltaY = -100;
+            }
+            m_dwDelayNum = (DWORD)sqrt((double)abs(m_dwDelayDeltaY)) * 5;
+            m_dwDelayLeft = m_dwDelayNum;
+            m_pManager->SetTimer(this, SCROLL_TIMERID, 50U);
+            return;
+        }
+        CTileLayoutUI::DoEvent(event);
+    }
 
 private:
-	UINT m_uButtonState;
-	POINT m_ptLastMouse;
-	LONG m_dwDelayDeltaY;
-	DWORD m_dwDelayNum;
-	DWORD m_dwDelayLeft;
+    UINT m_uButtonState;
+    POINT m_ptLastMouse;
+    LONG m_dwDelayDeltaY;
+    DWORD m_dwDelayNum;
+    DWORD m_dwDelayLeft;
 
-	int m_status = 1; //1:未处理 2:已确认 3:配送中 4:成功 5:失败 6:退款中
+    int m_status = 1; //1:未处理 2:已确认 3:配送中 4:成功 5:失败 6:退款中
 };