zhangyang 4 лет назад
Родитель
Сommit
bd4a24a6fa
35 измененных файлов с 1091 добавлено и 236 удалено
  1. 1 0
      .gitignore
  2. BIN
      bin/Win32/Debug/lewaimai_pos_windows/dump/2020-06-23-00-17-45.dmp
  3. 12 0
      bin/Win32/Debug/lewaimai_pos_windows/skin/chufang_printer_setting.xml
  4. 2 2
      bin/Win32/Debug/lewaimai_pos_windows/skin/main.xml
  5. 26 6
      bin/Win32/Debug/lewaimai_pos_windows/skin/setting.xml
  6. 9 5
      bin/Win32/Debug/lewaimai_pos_windows/skin/setting_chufang_printer_item.xml
  7. BIN
      bin/Win32/Release/lewaimai_pos_windows/db/pos.db
  8. 6 0
      bin/Win32/Release/lewaimai_pos_windows/log/pos.log
  9. 0 0
      bin/Win32/Release/lewaimai_pos_windows/log/pos_error.log
  10. BIN
      bin/Win32/Release/lewaimai_pos_windows/skin/skin.lwm
  11. BIN
      bin/Win32/Release/setup/qiaobawaimai_pos_windows_setup_1.0.2.8.exe
  12. 1 1
      bin/Win32/Release/setup/乐外卖接单软件安装脚本.nsi
  13. BIN
      dump/1.0.3.3/lewaimai_pos_windows.exe
  14. BIN
      dump/1.0.3.3/lewaimai_pos_windows.iobj
  15. BIN
      dump/1.0.3.3/lewaimai_pos_windows.ipdb
  16. BIN
      dump/1.0.3.3/lewaimai_pos_windows.pdb
  17. 21 0
      lewaimai_pos_windows/network/CLewaimaiHttpClient.cpp
  18. 5 0
      lewaimai_pos_windows/network/CLewaimaiHttpClient.h
  19. 4 1
      lewaimai_pos_windows/order/CWaimaiOrder.cpp
  20. 4 1
      lewaimai_pos_windows/order/CWaimaiOrder.h
  21. BIN
      lewaimai_pos_windows/resource/lewaimai_pos_windows.aps
  22. BIN
      lewaimai_pos_windows/resource/lewaimai_pos_windows.rc
  23. 183 35
      lewaimai_pos_windows/tool/CPosPrinter.cpp
  24. 2 2
      lewaimai_pos_windows/tool/CPosPrinter.h
  25. 21 2
      lewaimai_pos_windows/tool/CSetting.cpp
  26. 42 2
      lewaimai_pos_windows/tool/CSetting.h
  27. 240 103
      lewaimai_pos_windows/tool/CSqlite3.cpp
  28. 127 31
      lewaimai_pos_windows/wnd/CChufangSettingWnd.h
  29. 281 12
      lewaimai_pos_windows/wnd/CMainWnd.cpp
  30. 7 7
      lewaimai_pos_windows_server/helper/CAliyunMNS.cpp
  31. 1 1
      lewaimai_pos_windows_server/helper/CConfigReader.cpp
  32. 3 1
      lewaimai_pos_windows_server/main.cpp
  33. 45 11
      lewaimai_pos_windows_server/network/CClientSession.cpp
  34. 43 13
      lewaimai_pos_windows_server/network/CServer.cpp
  35. 5 0
      lewaimai_pos_windows_server/network/PosMessage.h

+ 1 - 0
.gitignore

@@ -5,3 +5,4 @@
 /bin/Win32/Debug/lewaimai_pos_windows/lewaimai_pos_windows.exe
 /bin/Win32/Debug/lewaimai_pos_windows/db
 /bin/Win32/Release/lewaimai_pos_windows/lewaimai_pos_windows.exe
+/bin/x64

BIN
bin/Win32/Debug/lewaimai_pos_windows/dump/2020-06-23-00-17-45.dmp


+ 12 - 0
bin/Win32/Debug/lewaimai_pos_windows/skin/chufang_printer_setting.xml

@@ -32,6 +32,18 @@
 				<Label text="分单打印" width="160" />
 				<CheckBox name="chufang_setting_fendan" padding="0,5,0,5" width="72" height="45" normalimage="file='switchbutton.png' source='0,0,143,91'" selectedimage="file='switchbutton.png' source='0,182,143,273'"/>
 			</HorizontalLayout>
+
+			<HorizontalLayout height="56" valign="center">
+				<Label text="分类打印" width="160" />
+				<CheckBox name="chufang_setting_fenlei" padding="0,5,0,5" width="72" height="45" normalimage="file='switchbutton.png' source='0,0,143,91'" selectedimage="file='switchbutton.png' source='0,182,143,273'"/>
+			</HorizontalLayout>
+			
+			<VerticalLayout name="chufang_setting_fenlei_xuanze">
+				<Label text="请在下面勾选需要打印的商品分类" height="30"/>
+				<VerticalLayout name="chufang_setting_fenlei_xuanze_area">
+					
+				</VerticalLayout>
+			</VerticalLayout>
 		</VerticalLayout>
 		
 		<HorizontalLayout height="56" valign="center" padding="0,30,0,20">

+ 2 - 2
bin/Win32/Debug/lewaimai_pos_windows/skin/main.xml

@@ -12,8 +12,8 @@
     		<Control height="1" bkcolor="#FF1B4876" />
     		<Control height="2" bkcolor="#FFD1EDFF" />
     		<HorizontalLayout height="90" bkcolor="#FF8DD3FF" bkcolor2="#FF60B1FE">
-    			<VerticalLayout width="200">
-    				<Label name="main_name_version" text="外卖接单软件" padding="5,5,0,0"/>
+    			<VerticalLayout width="600">
+    				<Label name="main_name_version" text="俏巴外卖接单软件" padding="5,5,0,0"/>
     			</VerticalLayout>
     			<HorizontalLayout childpadding="20" inset="10,16,10,10" >    				
     				<Control />

+ 26 - 6
bin/Win32/Debug/lewaimai_pos_windows/skin/setting.xml

@@ -134,6 +134,24 @@
 						<Combo name="setting_biaoqian_printer_usb" padding="0,9,0,0" width="800" height="26" tooltip="请点击这里选择您的标签打印机usb端口" normalimage="file='Setting_Combox_Normal.png' corner='2,2,24,2'" hotimage="file='Setting_Combox_Hover.png' corner='2,2,24,2'" pushedimage="Setting_Combox_Click.png' corner='2,2,24,2'" textpadding="10,1,1,1" >
 						</Combo>
 					</HorizontalLayout>
+					
+					<HorizontalLayout height="44">
+						<Label text="标签纸尺寸规格" width="260"/>
+						<Combo name="setting_biaoqian_printer_guige" padding="0,9,0,0" width="140" height="26" tooltip="请点击这里选择您的标签纸尺寸规格" normalimage="file='Setting_Combox_Normal.png' corner='2,2,24,2'" hotimage="file='Setting_Combox_Hover.png' corner='2,2,24,2'" pushedimage="Setting_Combox_Click.png' corner='2,2,24,2'" textpadding="10,1,1,1" >
+							<ListLabelElement text="40*30mm" selected="true" />
+							<ListLabelElement text="35*25mm" />
+							<ListLabelElement text="30*25mm" />
+							<ListLabelElement text="30*20mm" />
+						</Combo>
+					</HorizontalLayout>
+					
+					<HorizontalLayout height="44">
+						<Label text="出纸方向" width="260"/>
+						<Combo name="setting_biaoqian_printer_fangxiang" padding="0,9,0,0" width="140" height="26" tooltip="请点击这里选择您的标签纸出纸方向" normalimage="file='Setting_Combox_Normal.png' corner='2,2,24,2'" hotimage="file='Setting_Combox_Hover.png' corner='2,2,24,2'" pushedimage="Setting_Combox_Click.png' corner='2,2,24,2'" textpadding="10,1,1,1" >
+							<ListLabelElement text="正方向" selected="true" />
+							<ListLabelElement text="反方向" />
+						</Combo>
+					</HorizontalLayout>
 				</VerticalLayout>
 
 				<VerticalLayout bkcolor="#FFFFFFFF" padding="0,20,20,20" inset="15,15,15,15">
@@ -144,13 +162,15 @@
 					<HorizontalLayout height="44" padding="0,30,0,20">
 						<Button name="setting_new_chufang_printer_btn" align="center" width="200" height="38" padding="0,3,0,3" text="新建厨房打印机" normalimage="file='Btn_White.png' corner='5,5,5,5'" hotimage="file='Btn_White_Hover.png' corner='5,5,5,5'" pushedimage="file='Btn_White_Click.png' corner='5,5,5,5'" />
 					</HorizontalLayout>
-					<List name="setting_chufang_printer_list" bordersize="1" bordercolor="#FF000000" itemlinecolor="#FF000000" vscroll="true">
+					<List name="setting_chufang_printer_list" bordersize="1" bordercolor="#FF000000" itemlinecolor="#FF000000" vscrollbar="true" hscrollbar="true">
 						<ListHeader />
 						<ListHeaderItem text="打印机名称" width="180" align="center" />
-						<ListHeaderItem text="IP地址" width="160" align="center" />
-						<ListHeaderItem text="打印机规格" width="100" align="center" />
-						<ListHeaderItem text="商品分单打印" width="100" align="center" />
-						<ListHeaderItem text="操作" align="center" />
+						<ListHeaderItem text="IP地址" width="150" align="center" />
+						<ListHeaderItem text="打印机规格" width="150" align="center" />
+						<ListHeaderItem text="商品分单打印" width="150" align="center" />
+						<ListHeaderItem text="按商品分类打印" width="150" align="center" />
+						<ListHeaderItem text="关联商品分类" width="300" align="center" />
+						<ListHeaderItem text="操作" width="200" align="center"/>
 					</List> 
 				</VerticalLayout>
 
@@ -171,7 +191,7 @@
 
 				<VerticalLayout bkcolor="#FFFFFFFF" padding="0,20,20,20" inset="15,15,15,15">
 					<Control height="300" />
-					<Label text="外卖接单软件" align="center">
+					<Label text="俏巴外卖接单软件" align="center">
 					</Label>
 					<Label name="setting_version" text="版本号:1.0.0.1" align="center">
 					</Label>

+ 9 - 5
bin/Win32/Debug/lewaimai_pos_windows/skin/setting_chufang_printer_item.xml

@@ -3,11 +3,15 @@
 <Window> 
 	<ListContainerElement name="setting_chufang_printer_item" height="80"> 
 		<HorizontalLayout> 
-			<Label name="setting_chufang_printer_item_name" width="180" align="center"/> 
-			<Label name="setting_chufang_printer_item_ip" width="160" align="center"/> 
-			<Label name="setting_chufang_printer_guige" width="100" align="center"/>
-			<Label name="setting_chufang_printer_fendan" width="100" align="center"/>
-			<HorizontalLayout name="setting_chufang_printer_caozuo" align="center">
+			<Label name="setting_chufang_printer_item_name" width="180" height="80" align="center"/> 
+			<Label name="setting_chufang_printer_item_ip" width="150" align="center"/> 
+			<Label name="setting_chufang_printer_guige" width="150" align="center"/>
+			<Label name="setting_chufang_printer_fendan" width="150" align="center"/> 
+			<Label name="setting_chufang_printer_item_fenlei" width="150" align="center"/> 
+			<HorizontalLayout width="300" height="80" valign="center">
+				<Label name="setting_chufang_printer_item_fenlei_ids" width="200" multiline="true" align="center" valign="center"/> 
+			</HorizontalLayout>
+			<HorizontalLayout name="setting_chufang_printer_caozuo" width="200" align="center">
 				<Control></Control>
 				<Button name="setting_chufang_printer_item_update_btn" align="center" width="26" height="27" padding="20,25,0,0" normalimage="file='Setting_Btn.png'" hotimage="file='Setting_Btn_Hover.png'" pushedimage="file='Setting_Btn_Active.png'" />
 				<Button name="setting_chufang_printer_item_delete_btn" align="center" width="18" height="18" padding="20,29,0,0" normalimage="file='Delete_Members_Icon.png'" hotimage="file='Delete_Members_Icon_Hover.png'" pushedimage="file='Delete_Members_Icon_Click.png'" />

BIN
bin/Win32/Release/lewaimai_pos_windows/db/pos.db


+ 6 - 0
bin/Win32/Release/lewaimai_pos_windows/log/pos.log

@@ -0,0 +1,6 @@
+2021-02-02 22:59:25[INFO] - folderPath:D:\work\lewaimai_pos_windows\bin\Win32\Release\lewaimai_pos_windows\db,没有找到对应的目录,即将创建 [d:\work\lewaimai_pos_windows\lewaimai_pos_windows\tool\csqlite3.cpp:11]
+2021-02-02 22:59:25[INFO] - 新建 db 目录成功! [d:\work\lewaimai_pos_windows\lewaimai_pos_windows\tool\csqlite3.cpp:18]
+2021-02-02 22:59:25[INFO] - create table success [d:\work\lewaimai_pos_windows\lewaimai_pos_windows\tool\csqlite3.cpp:178]
+2021-02-02 22:59:25[INFO] - fount field [d:\work\lewaimai_pos_windows\lewaimai_pos_windows\tool\csqlite3.cpp:249]
+2021-02-02 22:59:25[INFO] - fount field [d:\work\lewaimai_pos_windows\lewaimai_pos_windows\tool\csqlite3.cpp:314]
+2021-02-02 22:59:48[INFO] - 可用的USB打印机数量:0 [d:\work\lewaimai_pos_windows\lewaimai_pos_windows\tool\cposprinter.cpp:29]

+ 0 - 0
bin/Win32/Release/lewaimai_pos_windows/log/pos_error.log


BIN
bin/Win32/Release/lewaimai_pos_windows/skin/skin.lwm


BIN
bin/Win32/Release/setup/qiaobawaimai_pos_windows_setup_1.0.2.8.exe


+ 1 - 1
bin/Win32/Release/setup/乐外卖接单软件安装脚本.nsi

@@ -2,7 +2,7 @@
 
 ; HM NIS Edit Wizard helper defines
 !define PRODUCT_NAME "俏巴外卖接单软件"
-!define PRODUCT_VERSION "1.0.2.8"
+!define PRODUCT_VERSION "1.0.3.3"
 !define PRODUCT_PUBLISHER "河南俏巴计算机信息有限公司"
 !define PRODUCT_WEB_SITE "https://www.qiaoba.ren"
 !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${PRODUCT_NAME}.exe"

BIN
dump/1.0.3.3/lewaimai_pos_windows.exe


BIN
dump/1.0.3.3/lewaimai_pos_windows.iobj


BIN
dump/1.0.3.3/lewaimai_pos_windows.ipdb


BIN
dump/1.0.3.3/lewaimai_pos_windows.pdb


+ 21 - 0
lewaimai_pos_windows/network/CLewaimaiHttpClient.cpp

@@ -78,6 +78,22 @@ bool CLewaimaiHttpClient::Login(std::string& errmsg)
 			errmsg = CLewaimaiString::UnicodeToUTF8(L"俏巴外卖PC版仅支持商户类型的子账号登录");
 			return false;
 		}
+
+		//获取店铺ID
+
+		//店铺ID默认为0
+		m_client.m_shop_id = "0";
+
+		rapidjson::Value& v_rows = data["shop_ids"];
+
+		for (rapidjson::SizeType i = 0; i < v_rows.Size(); ++i)
+		{
+			rapidjson::Value& v_row_i = v_rows[i];
+
+			std::string shop_id = v_row_i.GetString();
+
+			m_client.m_shop_id = shop_id;
+		}
 	}
 
 	//LOG_INFO("login success!");
@@ -160,3 +176,8 @@ bool CLewaimaiHttpClient::Request(std::string url, std::map<string, string> para
 
 	return false;
 }
+
+std::string CLewaimaiHttpClient::getShopId()
+{
+	return m_client.m_shop_id;
+}

+ 5 - 0
lewaimai_pos_windows/network/CLewaimaiHttpClient.h

@@ -15,6 +15,8 @@ public:
 
 	static bool Request(std::string url, std::map<string, string> params, std::string& response);
 
+	static std::string getShopId();
+
 public:
 	static CLewaimaiHttpClient m_client;
 
@@ -23,5 +25,8 @@ private:
 	std::string m_password;
 
 	std::string m_url = "https://api.lewaimai.com/seller";
+
+	//这个是当前登陆的账号对应的店铺ID(如果是连锁店账号就是返回的第一个店铺),主要用于厨房打印的分类打印时候用于获取商品分类
+	std::string m_shop_id;
 };
 

+ 4 - 1
lewaimai_pos_windows/order/CWaimaiOrder.cpp

@@ -106,6 +106,7 @@ bool CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 			m_open_selftake = data["open_selftake"].GetString();
 			m_delivery_date = data["delivery_date"].GetString();
 
+			m_showordernum = data["showordernum"].GetString();
 			m_customer_order_total = data["customer_order_total"].GetString();
 
 			m_printer_tip_name = data["printer_tip_name"].GetString();
@@ -123,7 +124,7 @@ bool CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 				newItem.m_food_name = v_row_i["food_name"].GetString();
 				newItem.m_item_price = v_row_i["item_price"].GetString();
 				newItem.m_quantity = v_row_i["quantity"].GetString();
-				//newItem.m_type_id = v_row_i["type_id"].GetString();
+				newItem.m_type_id = v_row_i["type_id"].GetString();
 				newItem.m_foodpackage_id = v_row_i["foodpackage_id"].GetString();
 				newItem.m_is_foodpackage = v_row_i["is_foodpackage"].GetString();
 
@@ -161,6 +162,8 @@ bool CWaimaiOrder::InitData(std::string order_id, std::string order_no)
 			m_show_qiangdan_qrcode = data["show_qiangdan_qrcode"].GetString();
 
 			m_manzeng_name = data["manzeng_name"].GetString();
+
+			m_show_whole_phone = data["show_whole_phone"].GetString();
 		}
 	}
 

+ 4 - 1
lewaimai_pos_windows/order/CWaimaiOrder.h

@@ -9,7 +9,7 @@ public:
 	std::string m_food_name;
 	std::string m_item_price;
 	std::string m_quantity;
-	//std::string m_type_id;
+	std::string m_type_id;
 	std::string m_foodpackage_id;
 	std::string m_is_foodpackage;
 };
@@ -95,6 +95,7 @@ public:
 	std::string m_open_selftake;
 	std::string m_delivery_date;
 
+	std::string m_showordernum;
 	std::string m_customer_order_total;
 
 	std::string m_printer_tip_name;
@@ -108,5 +109,7 @@ public:
 	std::string m_show_qiangdan_qrcode;
 
 	std::string m_manzeng_name;
+
+	std::string m_show_whole_phone;
 };
 

BIN
lewaimai_pos_windows/resource/lewaimai_pos_windows.aps


BIN
lewaimai_pos_windows/resource/lewaimai_pos_windows.rc


+ 183 - 35
lewaimai_pos_windows/tool/CPosPrinter.cpp

@@ -412,7 +412,8 @@ int CPosPrinter::GetDevicePath(LPGUID lpGuid, int usbType)
 }
 
 /*
- *返回打印机的类型, 1:普通热敏打印机 2:标签打印机
+ *返回打印机的类型, 1:普通热敏打印机 2:标签打印机 3:发票打印机
+ *这里因为不同厂家对vid pid定义不一样,有时候会出现佳博的标签打印机的vid和pid,在别的品牌上变成了热敏打印机,这里如果排除掉别的品牌的热敏打印机就无法打印了,所以这里不能轻易排除
  **/
 int CPosPrinter::GetPrinterType(wstring vid, wstring pid)
 {
@@ -421,6 +422,11 @@ int CPosPrinter::GetPrinterType(wstring vid, wstring pid)
         //佳博标签打印机
         return 2;
     }
+	else if (vid == L"XXX" && pid == L"XXX")
+	{
+		//发票打印机
+		return 3;
+	}
 
     return 1;
 }
@@ -480,6 +486,8 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
         {
             std::string err = e.what();
             LOG_INFO("网口打印机连接失败,IP地址:" << wangkou_ip.c_str() << ",错误信息:" << err.c_str());
+
+			MessageBoxW(NULL, (L"厨房网口打印机连接失败,IP地址:" + CLewaimaiString::UTF8ToUnicode(wangkou_ip)).c_str(), L"打印机连接失败", MB_OK);
         }
     }
 
@@ -616,6 +624,13 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
         if(order.m_is_selftake != "1")
         {
             string name = "姓名:" + CLewaimaiString::UTF8ToANSI(order.m_customer_name);
+			
+			//把下单次数也一起打印
+			if (order.m_showordernum == "1")
+			{
+				name += "(第 " + CLewaimaiString::UTF8ToANSI(order.m_customer_order_total) + " 次下单)";
+			}
+
             POS_TextOut(name, false, setting_printer_name_big);
             POS_FeedLine();
         }
@@ -628,6 +643,12 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
             setting_printer_phone_big = true;
         }
 
+		//看看电话是否要脱敏
+		if (order.m_show_whole_phone == "0")
+		{
+			order.m_phone.replace(3, 4, 4, '*');
+		}
+
         string phone = "电话:" + CLewaimaiString::UTF8ToANSI(order.m_phone);
         POS_TextOut(phone, false, setting_printer_phone_big);
         POS_FeedLine();
@@ -937,11 +958,51 @@ void CPosPrinter::PrintWaimaiOrderBiaoqian(CWaimaiOrder& order)
     std::string printer_usb = CSetting::GetParam("setting_biaoqian_printer_usb");
     std::wstring ws_printer_usb = CLewaimaiString::UTF8ToUnicode(printer_usb);
 
+	//读取标签纸的规格和方向
+	int biaoqian_width, biaoqian_height;
+	std::string printer_guige = CSetting::GetParam("setting_biaoqian_printer_guige");
+	if (printer_guige == "40*30mm")
+	{
+		biaoqian_width = 40;
+		biaoqian_height = 30;
+	}
+	else  if (printer_guige == "35*25mm")
+	{
+		biaoqian_width = 35;
+		biaoqian_height = 25;
+	}
+	else  if (printer_guige == "30*25mm")
+	{
+		biaoqian_width = 30;
+		biaoqian_height = 25;
+	}
+	else  if (printer_guige == "30*20mm")
+	{
+		biaoqian_width = 30;
+		biaoqian_height = 20;
+	}
+	else
+	{
+		biaoqian_width = 40;
+		biaoqian_height = 30;
+	}
+
+	int nDIRECTION;
+	std::string printer_fangxiang = CSetting::GetParam("setting_biaoqian_printer_fangxiang");
+	if (printer_fangxiang ==  "1")
+	{
+		nDIRECTION = 1;
+	}
+	else
+	{
+		nDIRECTION = 0;
+	}
+
     //连接usb端口
     InitOneUsb(ws_printer_usb);
 
 	//初始化标签打印机
-	BIAOQIAN_Reset();
+	BIAOQIAN_Reset(biaoqian_width, biaoqian_height, nDIRECTION);
 
     std::vector<CWaimaiOrderItem> cur_printer_use = order.m_order_items;
 
@@ -972,55 +1033,80 @@ void CPosPrinter::PrintWaimaiOrderBiaoqian(CWaimaiOrder& order)
 			std::string textData = "";
 
             curFoodNum++;
+			
+			//打印小票自定义名称
+			string printer_tip_name = CLewaimaiString::UTF8ToANSI(order.m_printer_tip_name);
+			if (printer_tip_name.length() == 0)
+			{
+				printer_tip_name = "外卖";
+			}
 
             std::string restaurant_number = order.m_restaurant_number;
-            std::string order_num_info = "外卖 #" + CLewaimaiString::UTF8ToANSI(restaurant_number);
-            textData += BIAOQIAN_TEXTGet(order_num_info, 16, 24, 1, 1);
+            std::string order_num_info = printer_tip_name + " #" + CLewaimaiString::UTF8ToANSI(restaurant_number);
+
+			//纸张宽度40mm的,是 320个点位(每mm8个),刚好可以放13个汉字,每个汉字宽度差不多是24,商品换行显示的时候,
+			//每行最多12个汉字,也就是空24个,因此这里设置12,刚好左右各空一半
+            textData += BIAOQIAN_TEXTGet(order_num_info, 12, 6, 1, 1);
 
             //打印份数
             std::string numInfo = to_string(curFoodNum) + "/" + to_string(foodNum);
-            textData += BIAOQIAN_TEXTGet(numInfo, 160, 24, 1, 1);
+            textData += BIAOQIAN_TEXTGet(numInfo, 180, 6, 1, 1);
 
             //每行最多显示12个汉字,这里要计算一下换行(要先转成ANSI格式)
             std::string handle_food_name = CLewaimaiString::UTF8ToANSI(food_name);
-            std::vector<std::string> foodNameVector = HandleBiaoqianFoodname(handle_food_name);
+            std::vector<std::string> foodNameVector = HandleBiaoqianFoodname(handle_food_name, biaoqian_width);
 
             int nRow = 0;
 
             //考虑是否用大号字体
             bool is_big_name = false;
 
+			/*暂时全部打印小字,这里注释掉
             if(foodNameVector.size() <= 2)
             {
                 //不超过2行,可以用大的字体
                 is_big_name = true;
-            }
-
-            LOG_INFO("foodNameVector size:" << foodNameVector.size());
+            }*/
 
+            //LOG_INFO("foodNameVector size:" << foodNameVector.size());
+			
             for(std::vector<std::string>::iterator it = foodNameVector.begin(); it != foodNameVector.end(); it++)
             {
                 LOG_INFO("nRow:" << nRow << ", 准备打印商品名字:" << (*it).c_str());
 
                 if(is_big_name)
                 {
-                    textData += BIAOQIAN_TEXTGet(*it, 16, 64 + 64 * nRow, 1, 2);
+                    textData += BIAOQIAN_TEXTGet(*it, 12, 42 + 60 * nRow, 1, 2);
                 }
                 else
                 {
-                    textData += BIAOQIAN_TEXTGet(*it, 16, 64 + 32 * nRow, 1, 1);
+                    textData += BIAOQIAN_TEXTGet(*it, 12, 42 + 30 * nRow, 1, 1);
                 }
 
                 nRow++;
             }
 
+			int nPriceY;
+			if (biaoqian_height ==  30)
+			{
+				nPriceY = 180;
+			}
+			else if (biaoqian_height == 25)
+			{
+				nPriceY = 140;
+			}
+			else if (biaoqian_height == 20)
+			{
+				nPriceY = 100;
+			}
+
             //打印价格
             std::string priceInfo = CLewaimaiString::UTF8ToANSI(food_price) + "元";
-            textData += BIAOQIAN_TEXTGet(priceInfo, 16, 188, 1, 1);
+            textData += BIAOQIAN_TEXTGet(priceInfo, 12, nPriceY, 1, 1);
 
             //打印订单号
             std::string order_num = "订单号:" + CLewaimaiString::UTF8ToANSI(order.m_order_num);
-            textData += BIAOQIAN_TEXTGet(order_num, 16, 218, 1, 1);
+            textData += BIAOQIAN_TEXTGet(order_num, 12, nPriceY + 30, 1, 1);
 
 			WriteData(textData);
 
@@ -1055,13 +1141,50 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
             std::string err = e.what();
             LOG_INFO("厨房网口打印机连接失败,IP地址:" << ip.c_str() << ",错误信息:" << err.c_str());
 
+			MessageBoxW(NULL, (L"厨房网口打印机连接失败,IP地址:" + CLewaimaiString::UTF8ToUnicode(ip)).c_str(), L"打印机连接失败", MB_OK);
+
             //连接失败了,处理下一个厨房打印机
             continue;
         }
 
         std::string guige = printer.guige;
         std::string fendan = printer.fendan;
-        std::vector<CWaimaiOrderItem> cur_printer_use = order.m_order_items;
+		std::string fenlei = printer.fenlei;
+		std::string fenlei_ids = printer.fenlei_ids;
+
+		std::vector<CWaimaiOrderItem> cur_printer_use;
+		if (fenlei == "0")
+		{
+			cur_printer_use = order.m_order_items;
+		}
+		else
+		{
+			//如果开启了分类打印,就要比对了
+			std::map<string, bool> ids_map;
+			std::vector<string> ids = CLewaimaiString::Split(fenlei_ids, ",");
+
+			for (std::vector<string>::iterator it = ids.begin(); it != ids.end(); it++)
+			{
+				ids_map[(*it)] = true;
+			}
+
+			for (std::vector<CWaimaiOrderItem>::iterator it = order.m_order_items.begin(); it != order.m_order_items.end(); it++)
+			{
+				if (ids_map.find((*it).m_type_id) != ids_map.end())
+				{
+					//如果当前商品的分类,在厨房打印机设置的分类里面,才加入
+					cur_printer_use.push_back(*it);
+				}
+			}
+		}
+
+		if (cur_printer_use.size() == 0)
+		{
+			//如果这个厨房打印机没有商品可以打印(开启了商品分类打印可能出现),就直接跳过
+			m_socket.close();
+
+			continue;
+		}
 
         if(fendan == "0")
         {
@@ -1075,14 +1198,14 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
 
             if(order.m_is_selftake == "1")
             {
-                POS_TextOut(order_type + "到店自取订单", false, false, 1);
+                POS_TextOut(order_type + "到店自取订单", false, true, 1);
                 POS_FeedLine();
 
                 POS_FeedLine();
             }
             else
             {
-                POS_TextOut(order_type + "外卖订单", false, false, 1);
+                POS_TextOut(order_type + "外卖订单", false, true, 1);
                 POS_FeedLine();
 
                 POS_FeedLine();
@@ -1094,7 +1217,7 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
                 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, false, 0);
+                    POS_TextOut(order_field, false, true, 0);
                     POS_FeedLine();
                 }
             }
@@ -1117,11 +1240,11 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
             //商品标题
             if(guige == "58")
             {
-                POS_TextOut("商品              单价 数量 金额");
+                POS_TextOut("商品              单价 数量 金额", false, true);
             }
             else
             {
-                POS_TextOut("商品                            单价  数量  金额");
+                POS_TextOut("商品                            单价  数量  金额", false, true);
             }
 
             POS_FeedLine();
@@ -1164,12 +1287,12 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
                 std::string quantityShow = HandleFoodQuantity(quantity, nGuige);
                 std::string priceTotalShow = HandleFoodTotalPrice(food_total_price, nGuige);
                 std::string firstLineShow = firstLine + priceShow + quantityShow + priceTotalShow;
-                POS_TextOut(firstLineShow, false, false, 0);
+                POS_TextOut(firstLineShow, false, true, 0);
                 POS_FeedLine();
 
                 for(std::vector<string>::iterator it = m_names.begin() + 1; it != m_names.end(); it++)
                 {
-                    POS_TextOut((*it), false, false, 0);
+                    POS_TextOut((*it), false, true, 0);
                     POS_FeedLine();
                 }
             }
@@ -1179,7 +1302,7 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
             {
                 POS_FeedLine();
                 string address = "顾客备注:" + CLewaimaiString::UTF8ToANSI(order.m_memo);
-                POS_TextOut(address, false, false, 0);
+                POS_TextOut(address, false, true, 0);
                 POS_FeedLine();
             }
 
@@ -1214,14 +1337,14 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
 
                 if(order.m_is_selftake == "1")
                 {
-                    POS_TextOut(order_type + "到店自取订单", false, false, 1);
+                    POS_TextOut(order_type + "到店自取订单", false, true, 1);
                     POS_FeedLine();
 
                     POS_FeedLine();
                 }
                 else
                 {
-                    POS_TextOut(order_type + "外卖订单", false, false, 1);
+                    POS_TextOut(order_type + "外卖订单", false, true, 1);
                     POS_FeedLine();
 
                     POS_FeedLine();
@@ -1233,7 +1356,7 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
                     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, false, 0);
+                        POS_TextOut(order_field, false, true, 0);
                         POS_FeedLine();
                     }
                 }
@@ -1256,11 +1379,11 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
                 //商品标题
                 if(guige == "58")
                 {
-                    POS_TextOut("商品              单价 数量 金额");
+                    POS_TextOut("商品              单价 数量 金额", false, true);
                 }
                 else
                 {
-                    POS_TextOut("商品                            单价  数量  金额");
+                    POS_TextOut("商品                            单价  数量  金额", false, true);
                 }
 
                 POS_FeedLine();
@@ -1288,12 +1411,12 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
                 std::string quantityShow = HandleFoodQuantity(quantity, 2);
                 std::string priceTotalShow = HandleFoodTotalPrice(food_total_price, 2);
                 std::string firstLineShow = firstLine + priceShow + quantityShow + priceTotalShow;
-                POS_TextOut(firstLineShow, false, false, 0);
+                POS_TextOut(firstLineShow, false, true, 0);
                 POS_FeedLine();
 
                 for(std::vector<string>::iterator it = m_names.begin() + 1; it != m_names.end(); it++)
                 {
-                    POS_TextOut((*it), false, false, 0);
+                    POS_TextOut((*it), false, true, 0);
                     POS_FeedLine();
                 }
 
@@ -1302,7 +1425,7 @@ void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
                 {
                     POS_FeedLine();
                     string address = "顾客备注:" + CLewaimaiString::UTF8ToANSI(order.m_memo);
-                    POS_TextOut(address, false, false, 0);
+                    POS_TextOut(address, false, true, 0);
                     POS_FeedLine();
                 }
 
@@ -1382,6 +1505,11 @@ int CPosPrinter::WriteBuf(const unsigned char* buf, int len)
  **/
 bool CPosPrinter::PortTest(HANDLE hPort)
 {
+	//这里的话目前USB、串口、并口用的都是同步读写模式,有的打印机(比如一些发票打印机)CreateFile会成功,但是WriteFile会一直阻塞卡着,如果检测的话,
+	//在这里会一直卡住,因此这里的检测就不检测了,默认所有的都是连通的
+	//因此,对于智能识别模式,可能会出现无法打印(因为被某些usb打印设备阻塞),这种情况就只能手动选择USB模式,然后重新启动软件
+	return true;
+
     //标签打印机的查询状态指令
     char chInitCode[2] = { 0x1b, 0x40};
 
@@ -1748,11 +1876,11 @@ void CPosPrinter::POS_OutBmp(std::wstring ImagePath)
 	delete[] dataTmp;
 }
 
-void CPosPrinter::BIAOQIAN_Reset()
+void CPosPrinter::BIAOQIAN_Reset(int nWidth, int nHeight, int nDirection)
 {
     char endTag[3] = {0x0d, 0x0a, 0x00};
 
-    std::string size = "SIZE 40 mm, 30 mm";
+    std::string size = "SIZE " + to_string(nWidth) + " mm," + to_string(nHeight) + " mm";
     size += endTag;
 
     std::string gap = "GAP 2 mm,0 mm";
@@ -1764,6 +1892,9 @@ void CPosPrinter::BIAOQIAN_Reset()
     std::string density = "DENSITY 12";
     density += endTag;
 
+	std::string DIRECTION = "DIRECTION " + to_string(nDirection);
+	DIRECTION += endTag;
+
     std::string REFERENCE = "REFERENCE 0,0";
     REFERENCE += endTag;
 
@@ -1776,7 +1907,7 @@ void CPosPrinter::BIAOQIAN_Reset()
     std::string cls = "CLS";
     cls += endTag;
 
-    std::string data = size + gap + speed + density + REFERENCE + PEER + TEAR + cls;
+    std::string data = size + gap + speed + density + DIRECTION + REFERENCE + PEER + TEAR + cls;
 
     WriteData(data);
 }
@@ -2115,16 +2246,33 @@ std::string CPosPrinter::HandleFoodTotalPrice(std::string oldprice, int guige)
     }
 }
 
-std::vector<std::string> CPosPrinter::HandleBiaoqianFoodname(std::string oldname)
+std::vector<std::string> CPosPrinter::HandleBiaoqianFoodname(std::string oldname, int nBiaoqianWidth)
 {
     std::vector<std::string> newnameArray;
     int nHanzi, nZimu;
     CalWord(oldname, nHanzi, nZimu);
 
+	//文字内容的实际宽度,1个汉字算2个宽度,1个英文或者数字、标点算1个(40mm宽度最多打印12个汉字 )
     int nWidth = nHanzi * 2 + nZimu;
 
     //40 *30mmm的标签,宽度最大24
-    int maxWidth = 24;
+    int maxWidth;
+	if (nBiaoqianWidth == 40)
+	{
+		maxWidth = 24;
+	}
+	else if (nBiaoqianWidth == 35)
+	{
+		maxWidth = 21;
+	}
+	else if (nBiaoqianWidth == 30)
+	{
+		maxWidth = 18;
+	}
+	else
+	{
+		maxWidth = 24;
+	}
 
     if(nWidth <= maxWidth)
     {

+ 2 - 2
lewaimai_pos_windows/tool/CPosPrinter.h

@@ -72,7 +72,7 @@ private:
 	void POS_OutBmp(std::wstring ImagePath);
 
 	//标签打印机的处理方法
-	void BIAOQIAN_Reset();
+	void BIAOQIAN_Reset(int nWidth, int nHeight, int nDirection);
 	void BIAOQIAN_FORMFEED();
 	void BIAOQIAN_TEXTOUT(std::string content, int x, int y, int x_multiplication, int y_multiplication);
 	std::string BIAOQIAN_TEXTGet(std::string content, int x, int y, int x_multiplication, int y_multiplication);
@@ -89,7 +89,7 @@ private:
 	std::string HandleFoodTotalPrice(std::string oldprice, int guige = 1);
 
 	//对标签打印的名字进行换行处理
-	std::vector<std::string> HandleBiaoqianFoodname(std::string oldname);
+	std::vector<std::string> HandleBiaoqianFoodname(std::string oldname, int nBiaoqianWdith);
 
 private:
 	//收银小票打印的句柄组合

+ 21 - 2
lewaimai_pos_windows/tool/CSetting.cpp

@@ -6,6 +6,8 @@
 std::map<std::string, std::string> CSetting::m_paramsMap;
 std::vector<ChufangPrinter> CSetting::m_chufang_printers;
 std::mutex CSetting::m_mutex;
+std::vector<FoodType> CSetting::m_foodtypes;
+std::map<std::string, std::string> CSetting::m_foodtype_id_name;
 std::map<string, string> CSetting::m_users;
 std::string CSetting::m_username;
 std::string CSetting::m_password;
@@ -44,7 +46,7 @@ std::string CSetting::GetParam(std::string name)
 	return value;
 }
 
-void CSetting::AddChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, bool isSave)
+void CSetting::AddChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, std::string fenlei, std::string fenlei_ids, bool isSave)
 {
 	ChufangPrinter newPrinter;
 
@@ -53,6 +55,8 @@ void CSetting::AddChufangPrinter(std::string date, std::string name, std::string
 	newPrinter.ip = ip;
 	newPrinter.guige = guige;
 	newPrinter.fendan = fendan;
+	newPrinter.fenlei = fenlei;
+	newPrinter.fenlei_ids = fenlei_ids;
 
 	m_chufang_printers.push_back(newPrinter);
 
@@ -62,7 +66,7 @@ void CSetting::AddChufangPrinter(std::string date, std::string name, std::string
 	}
 }
 
-void CSetting::UpdateChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, bool isSave)
+void CSetting::UpdateChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, std::string fenlei, std::string fenlei_ids, bool isSave)
 {
 	for (std::vector<ChufangPrinter>::iterator it = m_chufang_printers.begin(); it != m_chufang_printers.end(); it++)
 	{
@@ -72,6 +76,8 @@ void CSetting::UpdateChufangPrinter(std::string date, std::string name, std::str
 			(*it).ip = ip;
 			(*it).guige = guige;
 			(*it).fendan = fendan;
+			(*it).fenlei = fenlei;
+			(*it).fenlei_ids = fenlei_ids;
 
 			break;
 		}
@@ -258,6 +264,19 @@ void CSetting::Init()
 		m_paramsMap[setting_biaoqian_printer_usb] = "";
 	}
 
+	std::string setting_biaoqian_printer_guige = "setting_biaoqian_printer_guige";
+	if (m_paramsMap.find(setting_biaoqian_printer_guige) == m_paramsMap.end())
+	{
+		m_paramsMap[setting_biaoqian_printer_guige] = "40*30mm";
+	}
+
+	std::string setting_biaoqian_printer_fangxiang = "setting_biaoqian_printer_fangxiang";
+	if (m_paramsMap.find(setting_biaoqian_printer_fangxiang) == m_paramsMap.end())
+	{
+		//1表示正方向,0表示反方向
+		m_paramsMap[setting_biaoqian_printer_fangxiang] = "1";
+	}
+
 	//厨房打印的默认参数
 	std::string setting_is_new_waimai_chufang_printer = "setting_is_new_waimai_chufang_printer";
 	if (m_paramsMap.find(setting_is_new_waimai_chufang_printer) == m_paramsMap.end())

+ 42 - 2
lewaimai_pos_windows/tool/CSetting.h

@@ -10,6 +10,8 @@ public:
 	std::string ip;
 	std::string guige;
 	std::string fendan;
+	std::string fenlei;
+	std::string fenlei_ids;
 };
 
 class FoodType
@@ -30,8 +32,8 @@ public:
 	static std::string GetParam(std::string name);
 
 	//厨房打印机相关的参数配置
-	static void AddChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, bool isSave = true);
-	static void UpdateChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, bool isSave = true);
+	static void AddChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, std::string fenlei, std::string fenlei_ids, bool isSave = true);
+	static void UpdateChufangPrinter(std::string date, std::string name, std::string ip, std::string guige, std::string fendan, std::string fenlei, std::string fenlei_ids, bool isSave = true);
 	static void DelChufangPrinter(std::string date);
 
 	static ChufangPrinter GetChufangPrinter(std::string date);
@@ -79,6 +81,39 @@ public:
 		return m_chufang_printers;
 	}
 
+	static void ClearFoodtype()
+	{
+		m_foodtypes.clear();
+		m_foodtype_id_name.clear();
+	}
+
+	static void AddFoodtype(std::string name, std::string type_id)
+	{
+		FoodType newFoodType;
+		newFoodType.name = name;
+		newFoodType.type_id = type_id;
+
+		m_foodtypes.push_back(newFoodType);
+
+		m_foodtype_id_name[type_id] = name;
+	}
+
+	static std::vector<FoodType>& GetFoodtype()
+	{
+		return m_foodtypes;
+	}
+
+	static std::string getFoodtypeName(std::string type_id)
+	{
+		if (m_foodtype_id_name.find(type_id) != m_foodtype_id_name.end())
+		{
+			return m_foodtype_id_name[type_id];
+		}
+
+		//返回这个表示没找到这个分类
+		return "zhipuzi_not_found_xxx";
+	}
+
 	static void SetLoginInfo(std::string username, std::string password)
 	{
 		m_username = username;
@@ -113,6 +148,11 @@ private:
 
 	static std::mutex m_mutex;
 
+	static std::vector<FoodType> m_foodtypes;
+
+	//从商品分类的id到name的映射
+	static std::map<std::string, std::string> m_foodtype_id_name;
+
 	static std::map<string, string> m_users;
 
 	static std::string m_username;

+ 240 - 103
lewaimai_pos_windows/tool/CSqlite3.cpp

@@ -140,87 +140,222 @@ bool CSqlite3::InitConfig()
     sql = "SELECT COUNT(*) FROM sqlite_master where type = 'table' and name = 'pos_chufang_printer';";
 
     //读取厨房打印机的参数
-    if(sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
-    {
-        if(sqlite3_step(stmt) == SQLITE_ROW)
-        {
-            int count = sqlite3_column_int(stmt, 0);
-
-            if(count == 0)
-            {
-                //说明没找到这个表,那么这个时候新建这个表,先释放前面的stmt
-                sqlite3_finalize(stmt);
-                stmt = NULL;
-
-                sql = "CREATE TABLE pos_chufang_printer("  \
-                      "id         INTEGER          PRIMARY KEY AUTOINCREMENT,"\
-                      "date       CHAR(100)        NOT NULL," \
-                      "name       CHAR(100)        NOT NULL," \
-                      "ip         CHAR(100)        NOT NULL," \
-                      "guige      CHAR(100)        NOT NULL," \
-                      "fendan     CHAR(100)        NOT NULL);";
-
-                if(sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
-                {
-                    //执行该语句
-                    if(sqlite3_step(stmt) != SQLITE_DONE)
-                    {
-                        std::string err = sqlite3_errmsg(m_db);
-                        LOG_INFO("create table fail: " << err.c_str());
-
-                        sqlite3_finalize(stmt);
-                        return false;
-                    }
-
-                    //走到这里就是表创建成功了
-                    //LOG_INFO("create table success");
-                    sqlite3_finalize(stmt);
-                }
-
-                else
-                {
-                    LOG_INFO("create table prepare fail: " << sqlite3_errmsg(m_db));
-
-                    sqlite3_finalize(stmt);
-
-                    return false;
-                }
-            }
-
-            else
-            {
-                //说明已经有这个表了,就不用再创建了
-                sqlite3_finalize(stmt);
-            }
-
-            std::string sql = "SELECT * FROM pos_chufang_printer;";
-            sqlite3_stmt * stmt = NULL;
-
-            if(sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
-            {
-                while(sqlite3_step(stmt) == SQLITE_ROW)
-                {
-                    std::string date = (char*)sqlite3_column_text(stmt, 1);
-                    std::string name = (char*)sqlite3_column_text(stmt, 2);
-                    std::string ip = (char*)sqlite3_column_text(stmt, 3);
-                    std::string guige = (char*)sqlite3_column_text(stmt, 4);
-                    std::string fendan = (char*)sqlite3_column_text(stmt, 5);
-
-                    //这里仅仅是把数据库内容读到内存,所以之类用false
-                    CSetting::AddChufangPrinter(date, name, ip, guige, fendan, false);
-                }
-
-                sqlite3_finalize(stmt);
-            }
-
-            else
-            {
-                //异常情况
-                sqlite3_finalize(stmt);
-                return false;
-            }
-        }
-    }
+	if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+	{
+		if (sqlite3_step(stmt) == SQLITE_ROW)
+		{
+			int count = sqlite3_column_int(stmt, 0);
+
+			if (count == 0)
+			{
+				//说明没找到这个表,那么这个时候新建这个表,先释放前面的stmt
+				sqlite3_finalize(stmt);
+				stmt = NULL;
+
+				sql = "CREATE TABLE pos_chufang_printer("  \
+					"id         INTEGER          PRIMARY KEY AUTOINCREMENT,"\
+					"date       CHAR(100)        NOT NULL," \
+					"name       CHAR(100)        NOT NULL," \
+					"ip         CHAR(100)        NOT NULL," \
+					"guige      CHAR(100)        NOT NULL," \
+					"fendan     CHAR(100)        NOT NULL," \
+					"fenlei     CHAR(100)        NOT NULL," \
+					"fenlei_ids CHAR(2000)              );";
+
+				if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+				{
+					//执行该语句
+					if (sqlite3_step(stmt) != SQLITE_DONE)
+					{
+						std::string err = sqlite3_errmsg(m_db);
+						LOG_INFO("create table fail: " << err.c_str());
+
+						sqlite3_finalize(stmt);
+						return false;
+					}
+
+					//走到这里就是表创建成功了
+					LOG_INFO("create table success");
+					sqlite3_finalize(stmt);
+				}
+
+				else
+				{
+					LOG_INFO("create table prepare fail: " << sqlite3_errmsg(m_db));
+
+					sqlite3_finalize(stmt);
+
+					return false;
+				}
+			}
+
+			else
+			{
+				//说明已经有这个表了,就不用再创建了
+				sqlite3_finalize(stmt);
+			}
+
+			//兼容性检查,判断字段是否存在
+			std::string sql_pandduan = "select COUNT(*) from sqlite_master where type = 'table' and tbl_name = 'pos_chufang_printer' and sql like '%fenlei%';";
+			stmt = NULL;
+
+			if (sqlite3_prepare_v2(m_db, sql_pandduan.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+			{
+				if (sqlite3_step(stmt) == SQLITE_ROW)
+				{
+					int count = sqlite3_column_int(stmt, 0);
+
+					if (count == 0)
+					{
+						//说明没找到这个字段,准备添加字段
+						LOG_INFO("not fount field");
+						sqlite3_finalize(stmt);
+						stmt = NULL;
+
+						sql = "ALTER TABLE pos_chufang_printer "  \
+							"add fenlei     CHAR(100)         NOT NULL DEFAULT '0';";
+
+						LOG_INFO("sql:" << sql.c_str());
+
+						if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+						{
+							//执行该语句
+							if (sqlite3_step(stmt) != SQLITE_DONE)
+							{
+								std::string err = sqlite3_errmsg(m_db);
+								LOG_INFO("alter table fail: " << err.c_str());
+
+								sqlite3_finalize(stmt);
+								return false;
+							}
+
+							//走到这里就是表创建成功了
+							LOG_INFO("alter table success");
+							sqlite3_finalize(stmt);
+						}
+
+						else
+						{
+							LOG_INFO("alter table prepare fail: " << sqlite3_errmsg(m_db));
+
+							sqlite3_finalize(stmt);
+
+							return false;;
+						}
+					}
+
+					else
+					{
+						LOG_INFO("fount field");
+
+						//说明已经有这2个字段了
+						sqlite3_finalize(stmt);
+					}
+				}
+			}
+
+			else
+			{
+				//异常情况
+				sqlite3_finalize(stmt);
+				return false;
+			}
+
+			sql_pandduan = "select COUNT(*) from sqlite_master where type = 'table' and tbl_name = 'pos_chufang_printer' and sql like '%fenlei_ids%';";
+			stmt = NULL;
+
+			if (sqlite3_prepare_v2(m_db, sql_pandduan.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+			{
+				if (sqlite3_step(stmt) == SQLITE_ROW)
+				{
+					int count = sqlite3_column_int(stmt, 0);
+
+					if (count == 0)
+					{
+						//说明没找到这个字段,准备添加字段
+						LOG_INFO("not fount field");
+						sqlite3_finalize(stmt);
+						stmt = NULL;
+
+						sql = "ALTER TABLE pos_chufang_printer "  \
+							"add fenlei_ids CHAR(2000) NOT NULL DEFAULT '';";
+
+						LOG_INFO("sql:" << sql.c_str());
+
+						if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+						{
+							//执行该语句
+							if (sqlite3_step(stmt) != SQLITE_DONE)
+							{
+								std::string err = sqlite3_errmsg(m_db);
+								LOG_INFO("alter table fail: " << err.c_str());
+
+								sqlite3_finalize(stmt);
+								return false;
+							}
+
+							//走到这里就是表创建成功了
+							LOG_INFO("alter table success");
+							sqlite3_finalize(stmt);
+						}
+
+						else
+						{
+							LOG_INFO("alter table prepare fail: " << sqlite3_errmsg(m_db));
+
+							sqlite3_finalize(stmt);
+
+							return false;;
+						}
+					}
+
+					else
+					{
+						LOG_INFO("fount field");
+
+						//说明已经有这2个字段了
+						sqlite3_finalize(stmt);
+					}
+				}
+			}
+
+			else
+			{
+				//异常情况
+				sqlite3_finalize(stmt);
+				return false;
+			}
+
+			std::string sql = "SELECT * FROM pos_chufang_printer;";
+			stmt = NULL;
+
+			if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+			{
+				while (sqlite3_step(stmt) == SQLITE_ROW)
+				{
+					std::string date = (char*)sqlite3_column_text(stmt, 1);
+					std::string name = (char*)sqlite3_column_text(stmt, 2);
+					std::string ip = (char*)sqlite3_column_text(stmt, 3);
+					std::string guige = (char*)sqlite3_column_text(stmt, 4);
+					std::string fendan = (char*)sqlite3_column_text(stmt, 5);
+					std::string fenlei = (char*)sqlite3_column_text(stmt, 6);
+					std::string fenlei_ids = (char*)sqlite3_column_text(stmt, 7);
+
+					//这里仅仅是把数据库内容读到内存,所以之类用false
+					CSetting::AddChufangPrinter(date, name, ip, guige, fendan, fenlei, fenlei_ids, false);
+				}
+
+				sqlite3_finalize(stmt);
+			}
+
+			else
+			{
+				//异常情况
+				sqlite3_finalize(stmt);
+				return false;
+			}
+		}
+	}
 
     sql = "SELECT COUNT(*) FROM sqlite_master where type = 'table' and name = 'pos_user';";
 
@@ -334,33 +469,35 @@ bool CSqlite3::SaveParams(std::map<std::string, std::string>& params)
 
 bool CSqlite3::SaveChufangPrinter(std::vector<ChufangPrinter>& printers)
 {
-    int result = sqlite3_exec(m_db, "BEGIN;", 0, 0, 0);
+	int result = sqlite3_exec(m_db, "BEGIN;", 0, 0, 0);
 
-    std::string sql = "delete from pos_chufang_printer;";
-    result = sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
+	std::string sql = "delete from pos_chufang_printer;";
+	result = sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
 
-    for(std::vector<ChufangPrinter>::iterator it = printers.begin(); it != printers.end(); it++)
-    {
-        std::string date = (*it).date;
-        std::string name = (*it).name;
-        std::string ip = (*it).ip;
-        std::string guige = (*it).guige;
-        std::string fendan = (*it).fendan;
-
-        sql = "INSERT INTO pos_chufang_printer (date, name, ip, guige, fendan) VALUES ('" + date + "' ,'" + name + "','" + ip + "','" + guige + "','" + fendan + "')";
-        result = sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
-    }
+	for (std::vector<ChufangPrinter>::iterator it = printers.begin(); it != printers.end(); it++)
+	{
+		std::string date = (*it).date;
+		std::string name = (*it).name;
+		std::string ip = (*it).ip;
+		std::string guige = (*it).guige;
+		std::string fendan = (*it).fendan;
+		std::string fenlei = (*it).fenlei;
+		std::string fenlei_ids = (*it).fenlei_ids;
+
+		sql = "INSERT INTO pos_chufang_printer (date, name, ip, guige, fendan, fenlei, fenlei_ids) VALUES ('" + date + "' ,'" + name + "','" + ip + "','" + guige + "','" + fendan + "','" + fenlei + "','" + fenlei_ids + "')";
+		result = sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
+	}
 
-    result = sqlite3_exec(m_db, "COMMIT;", 0, 0, 0);
+	result = sqlite3_exec(m_db, "COMMIT;", 0, 0, 0);
 
-    if(result == SQLITE_OK)
-    {
-        LOG_INFO("save chufang printer success");
-        return true;
-    }
+	if (result == SQLITE_OK)
+	{
+		LOG_INFO("save params success");
+		return true;
+	}
 
-    LOG_INFO("save chufang printer fail:"<< sqlite3_errmsg(m_db));
-    return false;
+	LOG_INFO("save params fail");
+	return false;
 }
 
 bool CSqlite3::SaveUsers(std::map<string, string> users)

+ 127 - 31
lewaimai_pos_windows/wnd/CChufangSettingWnd.h

@@ -110,6 +110,70 @@ public:
 				fendan->Selected(false, false);
 			}
 		}
+
+		CCheckBoxUI* fenlei = static_cast<CCheckBoxUI*>(m_pm.FindControl(_T("chufang_setting_fenlei")));
+		if (m_mode == 1)
+		{
+			fenlei->Selected(false, false);
+		}
+		else
+		{
+			ChufangPrinter updatePrinter = CSetting::GetChufangPrinter(m_printer_date);
+			if (updatePrinter.fenlei == "1")
+			{
+				fenlei->Selected(true, false);
+			}
+			else
+			{
+				fenlei->Selected(false, false);
+			}
+		}
+
+		//把所有分类显示出来
+		CVerticalLayoutUI* pLayout = static_cast<CVerticalLayoutUI*>(m_pm.FindControl(_T("chufang_setting_fenlei_xuanze_area")));
+		pLayout->RemoveAll();
+
+		ChufangPrinter updatePrinter;
+
+		//这个map用于后面判断每个分类ID是否被选中
+		std::map<string, bool> ids_map;
+
+		if (m_mode == 2)
+		{
+			updatePrinter = CSetting::GetChufangPrinter(m_printer_date);
+			std::string foodtype_ids = updatePrinter.fenlei_ids;
+			std::vector<string> ids = CLewaimaiString::Split(foodtype_ids, ",");
+			for (std::vector<string>::iterator it = ids.begin(); it != ids.end(); it++)
+			{
+				ids_map[(*it)] = true;
+			}
+		}
+
+		std::vector<FoodType> foodtypes = CSetting::GetFoodtype();
+		for (std::vector<FoodType>::iterator it = foodtypes.begin(); it != foodtypes.end(); it++)
+		{
+			CDialogBuilder builder;
+			CListContainerElementUI* pEle = static_cast<CListContainerElementUI*>(builder.Create(_T("chufang_printer_setting_fenlei_select.xml"), (UINT)0, NULL, &m_pm));
+
+			CCheckBoxUI* pCheck = static_cast<CCheckBoxUI*>(pEle->FindSubControl(_T("chufang_setting_fenleli_xuanze_checkbox")));
+			pCheck->AddCustomAttribute(L"type_id", CLewaimaiString::UTF8ToUnicode((*it).type_id).c_str());
+
+			if (m_mode == 2)
+			{
+				if (ids_map.find((*it).type_id) != ids_map.end())
+				{
+					pCheck->Selected(true, false);
+				}
+			}
+
+			CLabelUI* pName = static_cast<CLabelUI*>(pEle->FindSubControl(_T("chufang_setting_fenleli_xuanze_name")));
+			pName->SetText(CLewaimaiString::UTF8ToUnicode((*it).name).c_str());
+
+			pLayout->Add(pEle);
+		}
+
+		CVerticalLayoutUI* pOutLayout = static_cast<CVerticalLayoutUI*>(m_pm.FindControl(_T("chufang_setting_fenlei_xuanze")));
+		pOutLayout->SetFixedHeight(foodtypes.size() * 30 + 30);
     }
 
     void Notify(TNotifyUI& msg)
@@ -126,11 +190,11 @@ public:
             else if(senderName == _T("chufang_setting_save"))
             {
                 //开始保存厨房打印机的数据
-                CEditUI* pName = static_cast<CEditUI*>(m_pm.FindControl(_T("chufang_setting_name")));
-                wstring wsName = pName->GetText();
+				CEditUI* pName = static_cast<CEditUI*>(m_pm.FindControl(_T("chufang_setting_name")));
+				wstring wsName = pName->GetText();
 
-                CEditUI* pIP = static_cast<CEditUI*>(m_pm.FindControl(_T("chufang_setting_ip")));
-                wstring wsIP = pIP->GetText();
+				CEditUI* pIP = static_cast<CEditUI*>(m_pm.FindControl(_T("chufang_setting_ip")));
+				wstring wsIP = pIP->GetText();
 
 				//判断IP的格式是否合法
 				if (CLewaimaiString::isIPAddressValid(CLewaimaiString::UnicodeToUTF8(wsIP).c_str()) == false)
@@ -142,29 +206,60 @@ public:
 					return;
 				}
 
-                CComboUI* com = static_cast<CComboUI*>(m_pm.FindControl(_T("chufang_setting_guige")));
-                wstring wsGuige;
-                if(com->GetCurSel() == 0)
-                {
-                    wsGuige = L"58";
-                }
-                else
-                {
-                    wsGuige = L"80";
-                }
-
-                CCheckBoxUI* pFendan = static_cast<CCheckBoxUI*>(m_pm.FindControl(_T("chufang_setting_fendan")));
-                wstring wsFendan;
-                if(pFendan->IsSelected())
-                {
-                    wsFendan = L"1";
-                }
-                else
-                {
-                    wsFendan = L"0";
-                }
-
-                //保存数据到数据库
+				CComboUI* com = static_cast<CComboUI*>(m_pm.FindControl(_T("chufang_setting_guige")));
+				wstring wsGuige;
+				if (com->GetCurSel() == 0)
+				{
+					wsGuige = L"58";
+				}
+				else
+				{
+					wsGuige = L"80";
+				}
+
+				CCheckBoxUI* pFendan = static_cast<CCheckBoxUI*>(m_pm.FindControl(_T("chufang_setting_fendan")));
+				wstring wsFendan;
+				if (pFendan->IsSelected())
+				{
+					wsFendan = L"1";
+				}
+				else
+				{
+					wsFendan = L"0";
+				}
+
+				CCheckBoxUI* pFenlei = static_cast<CCheckBoxUI*>(m_pm.FindControl(_T("chufang_setting_fenlei")));
+				wstring wsFenlei;
+				if (pFenlei->IsSelected())
+				{
+					wsFenlei = L"1";
+				}
+				else
+				{
+					wsFenlei = L"0";
+				}
+
+				std::string fenlei_ids = "";
+
+				CVerticalLayoutUI* pLayout = static_cast<CVerticalLayoutUI*>(m_pm.FindControl(_T("chufang_setting_fenlei_xuanze_area")));
+				CDuiPtrArray* pArray = m_pm.FindSubControlsByClass(pLayout, _T("CheckBox"));
+				int size = pArray->GetSize();
+				for (int i = 0; i < size; i++)
+				{
+					CCheckBoxUI* pBox = static_cast<CCheckBoxUI*>(pArray->GetAt(i));
+
+					if (pBox->IsSelected())
+					{
+						std::wstring ws_type_id = pBox->GetCustomAttribute(_T("type_id"));
+						std::string type_id = CLewaimaiString::UnicodeToUTF8(ws_type_id);
+
+						fenlei_ids += type_id + ",";
+					}
+				}
+
+				fenlei_ids = fenlei_ids.substr(0, fenlei_ids.size() - 1);
+
+				//保存数据到数据库
 
 				std::string date = to_string(time(NULL));
 
@@ -172,18 +267,19 @@ public:
 				std::string ip = CLewaimaiString::UnicodeToUTF8(wsIP);
 				std::string guige = CLewaimaiString::UnicodeToUTF8(wsGuige);
 				std::string fendan = CLewaimaiString::UnicodeToUTF8(wsFendan);
+				std::string fenlei = CLewaimaiString::UnicodeToUTF8(wsFenlei);
 
 				if (m_mode == 1)
 				{
-					CSetting::AddChufangPrinter(date, name, ip, guige, fendan, true);
+					CSetting::AddChufangPrinter(date, name, ip, guige, fendan, fenlei, fenlei_ids, true);
 				}
 				else
 				{
-					CSetting::UpdateChufangPrinter(m_printer_date, name, ip, guige, fendan, true);
+					CSetting::UpdateChufangPrinter(m_printer_date, name, ip, guige, fendan, fenlei, fenlei_ids, true);
 				}
 
-                Close(IDOK);
-                return;
+				Close(IDOK);
+				return;
             }
         }
     }

+ 281 - 12
lewaimai_pos_windows/wnd/CMainWnd.cpp

@@ -635,14 +635,19 @@ void CMainWnd::HandleClickMsg(TNotifyUI& msg)
             {
                 //这个时候是点击保存返回了,厨房打印机的数据已经建立好了,这个时候刷新表格的显示
                 CListUI* pPrinterList = static_cast<CListUI*>(m_pm.FindControl(_T("setting_chufang_printer_list")));
+
                 //把最后一个厨房打印机取出来
+
                 ChufangPrinter newPrinter = CSetting::getLastChufangPrinter();
                 CDialogBuilder builder;
                 CListContainerElementUI* pEle = static_cast<CListContainerElementUI*>(builder.Create(_T("setting_chufang_printer_item.xml"), (UINT)0, NULL, &m_pm));
+
                 CLabelUI* pName = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_name")));
                 pName->SetText(CLewaimaiString::UTF8ToUnicode(newPrinter.name).c_str());
+
                 CLabelUI* pIP = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_ip")));
                 pIP->SetText(CLewaimaiString::UTF8ToUnicode(newPrinter.ip).c_str());
+
                 CLabelUI* pGuige = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_guige")));
 
                 if(newPrinter.guige == "58")
@@ -665,6 +670,41 @@ void CMainWnd::HandleClickMsg(TNotifyUI& msg)
                     pFendan->SetText(L"否");
                 }
 
+                CLabelUI* pFenlei = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_fenlei")));
+
+                if(newPrinter.fenlei == "1")
+                {
+                    pFenlei->SetText(L"是");
+                }
+                else
+                {
+                    pFenlei->SetText(L"否");
+                }
+
+				std::string foodtypeNames = "";
+
+				std::string foodtype_ids = newPrinter.fenlei_ids;
+				std::vector<string> ids = CLewaimaiString::Split(foodtype_ids, ",");
+				for (std::vector<string>::iterator it = ids.begin(); it != ids.end(); it++)
+				{
+					std::string name = CSetting::getFoodtypeName((*it));
+					std::wstring ws_name = CLewaimaiString::UTF8ToUnicode(name);
+					if (name == "zhipuzi_not_found_xxx")
+					{
+						//这种情况是以前保存的分类后来被删掉了
+					}
+					else
+					{
+						foodtypeNames += name + "  ";
+					}
+				}
+
+				foodtypeNames = foodtypeNames.substr(0, foodtypeNames.size() - 1);
+				std::wstring ws_foodtypeNames = CLewaimaiString::UTF8ToUnicode(foodtypeNames);
+
+				CLabelUI* pFenleiIds = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_fenlei_ids")));
+				pFenleiIds->SetText(ws_foodtypeNames.c_str());
+
                 pEle->AddCustomAttribute(L"date", CLewaimaiString::UTF8ToUnicode(newPrinter.date).c_str());
                 pPrinterList->Add(pEle);
             }
@@ -756,6 +796,41 @@ void CMainWnd::HandleClickMsg(TNotifyUI& msg)
                 {
                     pFendan->SetText(L"否");
                 }
+
+				CLabelUI* pFenlei = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_fenlei")));
+
+				if (newPrinter.fenlei == "1")
+				{
+					pFenlei->SetText(L"是");
+				}
+				else
+				{
+					pFenlei->SetText(L"否");
+				}
+
+				std::string foodtypeNames = "";
+
+				std::string foodtype_ids = newPrinter.fenlei_ids;
+				std::vector<string> ids = CLewaimaiString::Split(foodtype_ids, ",");
+				for (std::vector<string>::iterator it = ids.begin(); it != ids.end(); it++)
+				{
+					std::string name = CSetting::getFoodtypeName((*it));
+					std::wstring ws_name = CLewaimaiString::UTF8ToUnicode(name);
+					if (name == "zhipuzi_not_found_xxx")
+					{
+						//这种情况是以前保存的分类后来被删掉了
+					}
+					else
+					{
+						foodtypeNames += name + "  ";
+					}
+				}
+
+				foodtypeNames = foodtypeNames.substr(0, foodtypeNames.size() - 1);
+				std::wstring ws_foodtypeNames = CLewaimaiString::UTF8ToUnicode(foodtypeNames);
+
+				CLabelUI* pFenleiIds = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_fenlei_ids")));
+				pFenleiIds->SetText(ws_foodtypeNames.c_str());
             }
         }
     }
@@ -1008,10 +1083,44 @@ void CMainWnd::HandleItemSelectMsg(TNotifyUI& msg)
     else if(name == _T("setting_biaoqian_printer_usb"))
     {
         CComboUI* com = static_cast<CComboUI*>(m_pm.FindControl(_T("setting_biaoqian_printer_usb")));
-		wstring usb_device = com->GetText();;
+        wstring usb_device = com->GetText();;
 
         CSetting::SetParam("setting_biaoqian_printer_usb", CLewaimaiString::UnicodeToUTF8(usb_device));
     }
+	else if (name == _T("setting_biaoqian_printer_guige"))
+	{
+		CComboUI* com = static_cast<CComboUI*>(m_pm.FindControl(_T("setting_biaoqian_printer_guige")));
+
+		if (com->GetCurSel() == 0)
+		{
+			CSetting::SetParam("setting_biaoqian_printer_guige", "40*30mm");
+		}
+		else if (com->GetCurSel() == 1)
+		{
+			CSetting::SetParam("setting_biaoqian_printer_guige", "35*25mm");
+		}
+		else if (com->GetCurSel() == 2)
+		{
+			CSetting::SetParam("setting_biaoqian_printer_guige", "30*25mm");
+		}
+		else if (com->GetCurSel() == 3)
+		{
+			CSetting::SetParam("setting_biaoqian_printer_guige", "30*20mm");
+		}
+	}
+	else if (name == _T("setting_biaoqian_printer_fangxiang"))
+	{
+		CComboUI* com = static_cast<CComboUI*>(m_pm.FindControl(_T("setting_biaoqian_printer_fangxiang")));
+
+		if (com->GetCurSel() == 0)
+		{
+			CSetting::SetParam("setting_biaoqian_printer_fangxiang", "1");
+		}
+		else if (com->GetCurSel() == 1)
+		{
+			CSetting::SetParam("setting_biaoqian_printer_fangxiang", "0");
+		}
+	}
 }
 
 LRESULT CMainWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -1092,7 +1201,7 @@ LRESULT CMainWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
 
 LRESULT CMainWnd::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
 {
-	return false;
+    return false;
 }
 
 LRESULT CMainWnd::OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@@ -1376,8 +1485,17 @@ LRESULT CMainWnd::OnLoginOut(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHan
 
 void CMainWnd::InitSettingStatus()
 {
+    //显示当前软件版本和登录账号信息
     CLabelUI* name_version = static_cast<CLabelUI*>(m_pm.FindControl(_T("main_name_version")));
-    name_version->SetText((L"俏巴外卖接单软件 " + CLewaimaiString::UTF8ToUnicode(CSystem::GetVersion())).c_str());
+
+    std::wstring wsShowName = L"俏巴外卖接单软件 " + CLewaimaiString::UTF8ToUnicode(CSystem::GetVersion());
+
+    std::string last_login_username = CSetting::GetParam("last_login_username");
+    std::wstring wx_last_login_username = CLewaimaiString::UTF8ToUnicode(last_login_username);
+
+    wsShowName += L"(登录账号:" + wx_last_login_username + L")";
+
+    name_version->SetText(wsShowName.c_str());
 
     CLabelUI* version = static_cast<CLabelUI*>(m_pm.FindControl(_T("setting_version")));
     version->SetText((L"版本号:" + CLewaimaiString::UTF8ToUnicode(CSystem::GetVersion())).c_str());
@@ -1728,16 +1846,16 @@ void CMainWnd::InitSettingStatus()
     }
 
     //初始化标签打印机的设置
-	box = static_cast<CCheckBoxUI*>(m_pm.FindControl(_T("setting_is_new_waimai_biaoqian_printer")));
+    box = static_cast<CCheckBoxUI*>(m_pm.FindControl(_T("setting_is_new_waimai_biaoqian_printer")));
 
-	if (CSetting::GetParam("setting_is_new_waimai_biaoqian_printer") == "1")
-	{
-		box->Selected(true, false);
-	}
-	else
-	{
-		box->Selected(false, false);
-	}
+    if(CSetting::GetParam("setting_is_new_waimai_biaoqian_printer") == "1")
+    {
+        box->Selected(true, false);
+    }
+    else
+    {
+        box->Selected(false, false);
+    }
 
     //usb下拉框默认选中
     CComboUI* com_usb = static_cast<CComboUI*>(m_pm.FindControl(_T("setting_biaoqian_printer_usb")));
@@ -1772,9 +1890,110 @@ void CMainWnd::InitSettingStatus()
     com_usb->SelectItem(nSelect, false, false);
     com_usb->SetText(CLewaimaiString::UTF8ToUnicode(setting_biaoqian_printer_usb).c_str());
 
+	com = static_cast<CComboUI*>(m_pm.FindControl(_T("setting_biaoqian_printer_guige")));
+	std::string setting_biaoqian_printer_guige = CSetting::GetParam("setting_biaoqian_printer_guige");
+
+	if (setting_biaoqian_printer_guige == "40*30mm")
+	{
+		com->SetInternVisible(true);
+		com->SelectItem(0, false, false);
+		com->SetText(L"40*30mm");
+	}
+	else if (setting_biaoqian_printer_guige == "35*25mm")
+	{
+		com->SetInternVisible(true);
+		com->SelectItem(1, false, false);
+		com->SetText(L"35*25mm");
+	}
+	else if (setting_biaoqian_printer_guige == "30*25mm")
+	{
+		com->SetInternVisible(true);
+		com->SelectItem(2, false, false);
+		com->SetText(L"30*25mm");
+	}
+	else if (setting_biaoqian_printer_guige == "30*20mm")
+	{
+		com->SetInternVisible(true);
+		com->SelectItem(3, false, false);
+		com->SetText(L"30*20mm");
+	}
+
+	com = static_cast<CComboUI*>(m_pm.FindControl(_T("setting_biaoqian_printer_fangxiang")));
+	std::string setting_biaoqian_printer_fangxiang = CSetting::GetParam("setting_biaoqian_printer_fangxiang");
+
+	if (setting_biaoqian_printer_fangxiang == "1")
+	{
+		com->SetInternVisible(true);
+		com->SelectItem(0, false, false);
+		com->SetText(L"正方向");
+	}
+	else if (setting_biaoqian_printer_fangxiang == "0")
+	{
+		com->SetInternVisible(true);
+		com->SelectItem(1, false, false);
+		com->SetText(L"反方向");
+	}
+
     //这里开始,初始化厨房打印机的设置
     CListUI* pPrinterList = static_cast<CListUI*>(m_pm.FindControl(_T("setting_chufang_printer_list")));
 
+    //获取当前店铺的商品分类信息,用于设置厨房打印机的分类打印
+
+    //先清空一次分类(主要考虑退出登陆重新登录的情况)
+    CSetting::ClearFoodtype();
+
+	std::string shop_id = CLewaimaiHttpClient::getShopId();
+	if (shop_id != "0")
+	{
+		std::map<string, string> params;
+		params["shop_id"] = shop_id;
+
+		std::string response;
+
+		std::string url = "/goodstype/getlist";
+
+		CLewaimaiHttpClient::Request(url.c_str(), params, response);
+
+		rapidjson::Document document;
+		document.Parse(response.c_str());
+
+		if (document.HasParseError())
+		{
+			LOG_INFO("parse response error!");
+			return;
+		}
+
+		if (!document.HasMember("errcode") || !document.HasMember("errmsg") || !document.HasMember("data"))
+		{
+			LOG_INFO("json error!");
+			return;
+		}
+
+		rapidjson::Value& v_errcode = document["errcode"];
+		int errcode = v_errcode.GetInt();
+
+		if (errcode != 0)
+		{
+			LOG_INFO("response failed! message:" << document["errmsg"].GetString());
+			return;
+		}
+
+		//获得数据成功,把分类信息保存起来
+		rapidjson::Value& data = document["data"];
+
+		rapidjson::Value& v_rows = data["goods_types"];
+
+		for (rapidjson::SizeType i = 0; i < v_rows.Size(); ++i)
+		{
+			rapidjson::Value& v_row_i = v_rows[i];
+
+			std::string type_id = v_row_i["type_id"].GetString();
+			std::string name = v_row_i["name"].GetString();
+
+			CSetting::AddFoodtype(name, type_id);
+		}
+	}
+
     //获取厨房打印机的集合
     std::vector<ChufangPrinter> printers = CSetting::getChufangPrints();
 
@@ -1812,6 +2031,56 @@ void CMainWnd::InitSettingStatus()
             pFendan->SetText(L"否");
         }
 
+        CLabelUI* pFenlei = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_fenlei")));
+
+        if(newPrinter.fenlei == "1")
+        {
+            pFenlei->SetText(L"是");
+        }
+        else
+        {
+            pFenlei->SetText(L"否");
+        }
+
+        std::string foodtypeNames = "";
+
+        std::string foodtype_ids = newPrinter.fenlei_ids;
+
+        //这个是删除掉不存在的type_id之后的
+        std::string new_foodtype_ids = "";
+
+        std::vector<string> ids = CLewaimaiString::Split(foodtype_ids, ",");
+
+        for(std::vector<string>::iterator it = ids.begin(); it != ids.end(); it++)
+        {
+            std::string name = CSetting::getFoodtypeName((*it));
+
+            if(name == "zhipuzi_not_found_xxx")
+            {
+                //这种情况是以前保存的分类后来被删掉了
+            }
+            else
+            {
+                foodtypeNames += name + "  ";
+
+                new_foodtype_ids += (*it) + ",";
+            }
+        }
+
+        //删掉不存在的type_id,更新内存和数据库
+        new_foodtype_ids = new_foodtype_ids.substr(0, new_foodtype_ids.length() - 1);
+
+        if(new_foodtype_ids.compare(foodtype_ids) != 0)
+        {
+            CSetting::UpdateChufangPrinter(newPrinter.date, newPrinter.name, newPrinter.ip, newPrinter.guige, newPrinter.fendan, newPrinter.fenlei, new_foodtype_ids, true);
+        }
+
+        foodtypeNames = foodtypeNames.substr(0, foodtypeNames.size() - 1);
+        std::wstring ws_foodtypeNames = CLewaimaiString::UTF8ToUnicode(foodtypeNames);
+
+        CLabelUI* pFenleiIds = static_cast<CLabelUI*>(pEle->FindSubControl(_T("setting_chufang_printer_item_fenlei_ids")));
+        pFenleiIds->SetText(ws_foodtypeNames.c_str());
+
         //设置标记属性,用于修改时候匹配
         pEle->AddCustomAttribute(L"date", CLewaimaiString::UTF8ToUnicode(newPrinter.date).c_str());
         pPrinterList->Add(pEle);

+ 7 - 7
lewaimai_pos_windows_server/helper/CAliyunMNS.cpp

@@ -19,11 +19,11 @@ CAliyunMNS::CAliyunMNS(std::string queueName)
     {
         queue = m_mnsClient->getQueueRef(queueName.c_str());
 
-        LOG_ERROR("queueName:" << queueName.c_str());
-        LOG_ERROR("endpoint:" << endpoint.c_str());
-        LOG_ERROR("accessId:" << accessId.c_str());
-        LOG_ERROR("accessKey:" << accessKey.c_str());
-        LOG_ERROR("stsToken:" << stsToken.c_str());
+        //LOG_ERROR("queueName:" << queueName.c_str());
+        //LOG_ERROR("endpoint:" << endpoint.c_str());
+        //LOG_ERROR("accessId:" << accessId.c_str());
+        //LOG_ERROR("accessKey:" << accessKey.c_str());
+        //LOG_ERROR("stsToken:" << stsToken.c_str());
 
         is_init = true;
     }
@@ -81,13 +81,13 @@ std::string CAliyunMNS::getMessage()
     catch(MNSServerException& me)
     {
         cout << "Request Failed: " << me.GetErrorCode().c_str() << endl;
-        //LOG_DEBUG("Request Failed: " << me.GetErrorCode().c_str());
+        LOG_INFO("Request Failed: " << me.GetErrorCode().c_str());
         return "error!";
     }
     catch(MNSExceptionBase& mb)
     {
         cout << "Request Failed: " << mb.ToString().c_str() << endl;
-        //LOG_DEBUG("Request Failed: " << mb.ToString().c_str());
+        LOG_INFO("Request Failed: " << mb.ToString().c_str());
         return "error!";
     }
 }

+ 1 - 1
lewaimai_pos_windows_server/helper/CConfigReader.cpp

@@ -19,7 +19,7 @@ void CConfigReader::ReadConfigFile()
 {
 	ifstream configFile;
 
-	string path = "../conf/lewaimai_pos_windows_server.conf";
+	string path = "/usr/local/lewaimai_pos_windows_server/conf/lewaimai_pos_windows_server.conf";
 
 	configFile.open(path.c_str());
 	string str_line;

+ 3 - 1
lewaimai_pos_windows_server/main.cpp

@@ -25,8 +25,10 @@ int main()
 	catch (std::exception& e)
 	{
 		std::cerr << "Exception: " << e.what() << "\n";
-		LOG_INFO("Exception: " << e.what());
+		LOG_ERROR("Exception: " << e.what());
 	}
 
+	LOG_ERROR("ready to exit program");
+
 	return 0;
 }

+ 45 - 11
lewaimai_pos_windows_server/network/CClientSession.cpp

@@ -12,6 +12,8 @@ CClientSession::~CClientSession()
 
 void CClientSession::start()
 {
+	m_pos_message.clear();
+
 	boost::asio::async_read(socket_, boost::asio::buffer(&m_pos_message, sizeof(PosMessage)),
 		boost::bind(&CClientSession::handle_read, this,
 			boost::asio::placeholders::error,
@@ -40,10 +42,19 @@ void CClientSession::stop()
 	//返回给接入层的消息
 	std::string login_out_msg = buffer.GetString();
 
-	send_message(login_out_msg);
+	bool ret = send_message(login_out_msg);
 
-	//然后关闭socket
-	socket_.close();
+	if (ret)
+	{
+		//然后关闭socket
+		LOG_INFO("in stop, send_message success!");
+		socket_.close();
+	}
+	else
+	{
+		LOG_ERROR("in stop, send_message failed!");
+		//如果同步写数据失败,说明socket已经失效了,这里不要调用关闭操作,等待异步读返回错误就好
+	}
 
 	//注意这里不能调用delete this,因为后面会异步返回,要判断状态,如果这里delete了,后面就会内存越界
 }
@@ -66,6 +77,8 @@ bool CClientSession::send_message(std::string msg)
 	{
 		std::string err = e.what();
 
+		LOG_ERROR("send_message error, message:" << err.c_str());
+
 		//注意这里是同步发送消息,这里不要处理socket的关闭和delete操作,让后面的异步读错误处理
 		return false;
 	}
@@ -90,7 +103,18 @@ void CClientSession::handle_read(const boost::system::error_code& error,
         document.Parse(msg.c_str());
         if(!document.IsObject())
         {
-            LOG_INFO("message 非法!");
+            LOG_ERROR("message 非法! msg:" << msg.c_str());
+			LOG_ERROR("msg length:" << m_pos_message.m_length);
+			LOG_ERROR("ip:" << socket_.remote_endpoint().address().to_string());
+
+			//处理完了,重新读取
+			m_pos_message.clear();
+
+			boost::asio::async_read(socket_, boost::asio::buffer(&m_pos_message, sizeof(PosMessage)),
+				boost::bind(&CClientSession::handle_read, this,
+					boost::asio::placeholders::error,
+					boost::asio::placeholders::bytes_transferred));
+
             return;
         }
 
@@ -103,7 +127,7 @@ void CClientSession::handle_read(const boost::system::error_code& error,
 
 		if (is_login == "1")
 		{
-			LOG_INFO("get client login message:" << msg.c_str());
+			//LOG_INFO("get client login message:" << msg.c_str());
 
 			//获取到用户名了,进行绑定
 			m_server->BindUsername(username, this);
@@ -113,25 +137,34 @@ void CClientSession::handle_read(const boost::system::error_code& error,
 		}
 
         //处理完了,重新读取
-        socket_.async_read_some(boost::asio::buffer(&m_pos_message, sizeof(PosMessage)),
-                                boost::bind(&CClientSession::handle_read, this,
-                                            boost::asio::placeholders::error,
-                                            boost::asio::placeholders::bytes_transferred));
+		m_pos_message.clear();
+
+		boost::asio::async_read(socket_, boost::asio::buffer(&m_pos_message, sizeof(PosMessage)),
+			boost::bind(&CClientSession::handle_read, this,
+				boost::asio::placeholders::error,
+				boost::asio::placeholders::bytes_transferred));
     }
     else
     {
 		std::string err = error.message();
+		//LOG_ERROR("handle_read error, err message:" << err.c_str());
 
 		if (socket_.is_open())
 		{
+			socket_.close();
+
 			//这个是客户端断开了链接
 			if (m_username == "")
 			{
-				//说明这个socket还没获取过用户名
+				//说明这个socket还没获取过用户名,直接销毁对象即可
+				LOG_ERROR("111 handle_read error, err message:" << err.c_str());
 				delete this;
 			}
 			else
 			{
+				//说明这个socket已经绑定过用户名了,先从map中删除,再销毁对象
+				LOG_ERROR("222 handle_read error, err message:" << err.c_str());
+				LOG_ERROR("222 username:" << m_username.c_str());
 				m_server->DeleteClient(m_username);
 
 				delete this;
@@ -139,7 +172,8 @@ void CClientSession::handle_read(const boost::system::error_code& error,
 		}
 		else
 		{
-			//这个是服务端断开了链接
+			//这个是服务端断开了链接,已经调用过close了
+			LOG_INFO("handle_read error,服务端断开了链接");
 			delete this;
 		}
     }

+ 43 - 13
lewaimai_pos_windows_server/network/CServer.cpp

@@ -10,16 +10,21 @@ CServer::CServer()
 
 CServer::~CServer()
 {
+	LOG_ERROR("start ~CServer");
 	delete acceptor_;
 
 	if (m_db != NULL)
 	{
 		sqlite3_close(m_db);
 	}
+
+	LOG_ERROR("end ~CServer");
 }
 
 void CServer::Init()
 {
+	LOG_ERROR("start Init()");
+
 	//初始化数据库
 	InitSqlLite();
 
@@ -31,7 +36,6 @@ void CServer::Init()
 	start_accept();
 
 	int n_cpu = CSystem::get_CPU_core_num();
-	LOG_INFO("cpu num:" << n_cpu);
 
 	//开始接受和处理mns的消息
 	for (int i = 0; i < n_cpu * 2; i++)
@@ -61,8 +65,19 @@ void CServer::Init()
 		t.detach();
 	}
 
-	//开始异步执行
-	io_context_.run();
+	LOG_ERROR("ready to run");
+
+	try
+	{
+		//开始异步执行
+		io_context_.run();
+	}
+	catch (std::exception& e)
+	{
+		LOG_ERROR("io_context Exception: " << e.what());
+	}
+
+	LOG_ERROR("stop run");
 }
 
 void CServer::InitSqlLite()
@@ -82,20 +97,20 @@ void CServer::InitSqlLite()
 	m_rc = sqlite3_open(s_path.c_str(), &m_db);
 #else
 	std::string db_path = CSystem::getAbsopath() + "../db/pos.db";
-	LOG_INFO("db path:" << db_path.c_str());
+	//LOG_INFO("db path:" << db_path.c_str());
 
 	m_rc = sqlite3_open(db_path.c_str(), &m_db);
 #endif
 
 	if (m_rc)
 	{
-		LOG_INFO("Can't open database: " << sqlite3_errmsg(m_db));
+		LOG_ERROR("Can't open database: " << sqlite3_errmsg(m_db));
 		return;
 	}
 
 	else
 	{
-		LOG_INFO("Opened database successfully");
+		//LOG_INFO("Opened database successfully");
 	}
 
 	//初始化数据表
@@ -281,12 +296,15 @@ void CServer::start_accept()
 void CServer::handle_accept(CClientSession* new_session,
 	const boost::system::error_code& error)
 {
+	//LOG_INFO("new client, handle_accept!");
+
 	if (!error)
 	{
 		new_session->start();
 	}
 	else
 	{
+		LOG_ERROR("handle_accept error");
 		delete new_session;
 	}
 
@@ -301,15 +319,24 @@ void CServer::BindUsername(std::string username, CClientSession* session)
 {
 	m_map_mutex.lock();
 
-	if (m_clients_map.find(username) != m_clients_map.end() && m_clients_map[username]->GetNum() < session->GetNum())
+	if (m_clients_map.find(username) != m_clients_map.end())
 	{
-		//之前已经存在了一个,先把之前的关闭掉(这个是服务器端主动的关闭)
-		m_clients_map[username]->stop();
+		if (m_clients_map[username]->GetNum() < session->GetNum())
+		{
+			//之前已经存在了一个,先把之前的关闭掉(这个是服务器端主动的关闭)
+			m_clients_map[username]->stop();
+		}
+		else
+		{
+			LOG_ERROR("异常情况,不应该出现");
+		}
 	}
 
 	m_clients_map[username] = session;
 
 	m_map_mutex.unlock();
+
+	LOG_INFO("绑定新客户端成功,当前客户端数量:" << m_clients_map.size());
 }
 
 void CServer::DeleteClient(std::string username)
@@ -322,6 +349,8 @@ void CServer::DeleteClient(std::string username)
 	}
 
 	m_map_mutex.unlock();
+
+	LOG_INFO("删除客户端成功,当前客户端数量:" << m_clients_map.size());
 }
 
 /*
@@ -337,7 +366,7 @@ void CServer::ReceiveMNSMessage()
         return;
     }
 
-	LOG_INFO("Init AliyunMNS success!");
+	//LOG_INFO("Init AliyunMNS success!");
 
     while(true)
     {
@@ -348,7 +377,7 @@ void CServer::ReceiveMNSMessage()
             continue;
         }
 
-        //LOG_INFO("get new message:" << message.c_str());
+		//LOG_INFO("new msn message:" << message.c_str());
 
         //获取到了新的消息,开始进行处理
         rapidjson::Document document;
@@ -356,6 +385,7 @@ void CServer::ReceiveMNSMessage()
         if(!document.IsObject())
         {
             LOG_INFO("message 非法!");
+			LOG_INFO("get new message:" << message.c_str());
             continue;
         }
 
@@ -389,7 +419,7 @@ void CServer::ReceiveMNSMessage()
 		if (time(NULL) > atoi(timestamp.c_str()) + atoi(use_time.c_str()))
 		{
 			//消息过了有效期,直接丢弃
-			LOG_INFO("message due date!");
+			//LOG_INFO("message due date!");
 			continue;
 		}		
 
@@ -466,7 +496,7 @@ void CServer::SendMessageToClient()
 			}
 			else
 			{
-				LOG_INFO("send to client success, username:" << username.c_str());
+				//LOG_INFO("send to client success, username:" << username.c_str());
 			}
 		}
 	}	

+ 5 - 0
lewaimai_pos_windows_server/network/PosMessage.h

@@ -7,4 +7,9 @@ public:
 	char data[max_length];
 
 	int m_length;
+
+	void clear()
+	{
+		memset(this, 0, sizeof(PosMessage));
+	}
 };