CPosPrinter.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036
  1. #include "../pch/pch.h"
  2. #include "CPosPrinter.h"
  3. #include "../tool/CComHelper.h"
  4. #include "../helper/CBitmapHelper.h"
  5. CPosPrinter::CPosPrinter(): m_socket(m_io)
  6. {
  7. }
  8. CPosPrinter::~CPosPrinter()
  9. {
  10. }
  11. /*
  12. *usbType是1表示只查找收银小票打印机,会排除已知的标签打印机
  13. *usbType为2表示所有usb打印机都查找,包含标签与非标签
  14. **/
  15. void CPosPrinter::InitUsb(int usbType)
  16. {
  17. //设置中文字符
  18. setlocale(LC_CTYPE, "chs");
  19. //取设备路径
  20. int nDevice = GetDevicePath((LPGUID)&USB_GUID, usbType);
  21. LOG_INFO("可用的USB打印机数量:" << nDevice);
  22. //添加usb端口
  23. int i = 0;
  24. while(i < nDevice)
  25. {
  26. LOG_INFO("准备打开端口 Port = " << m_usb_devices[i].c_str());
  27. HANDLE hPort = CreateFile(m_usb_devices[i].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  28. if(hPort == INVALID_HANDLE_VALUE)
  29. {
  30. // 打开端口失败
  31. DWORD error = GetLastError();
  32. if(error == 2)
  33. {
  34. //没有指定的文件
  35. LOG_INFO("没有找对对应的usb端口");
  36. }
  37. else if(error == 5)
  38. {
  39. LOG_INFO("usb端口被占用!");
  40. }
  41. continue;
  42. }
  43. LOG_INFO("打开usb端口,准备进行打印机检测! hPort:" << hPort);
  44. if(PortTest(hPort) == true)
  45. {
  46. //端口测试连通,保存起来
  47. PrinterHandle newHandle;
  48. newHandle.hPort = hPort;
  49. newHandle.type = 1;
  50. m_hPorts.push_back(newHandle);
  51. }
  52. else
  53. {
  54. //端口打印机没有连接,那么就直接关闭掉并口,避免占用
  55. CloseHandle(hPort);
  56. }
  57. i++;
  58. }
  59. }
  60. void CPosPrinter::InitOneUsb(wstring usb_path)
  61. {
  62. HANDLE hPort = CreateFile(usb_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  63. if(hPort == INVALID_HANDLE_VALUE)
  64. {
  65. // 打开端口失败
  66. DWORD error = GetLastError();
  67. if(error == 2)
  68. {
  69. //没有指定的文件
  70. LOG_INFO("没有找对对应的usb端口");
  71. }
  72. else if(error == 5)
  73. {
  74. LOG_INFO("usb端口被占用!");
  75. }
  76. }
  77. LOG_INFO("打开usb端口,准备进行打印机检测! hPort:" << hPort);
  78. if(PortTest(hPort) == true)
  79. {
  80. //端口测试连通,保存起来
  81. PrinterHandle newHandle;
  82. newHandle.hPort = hPort;
  83. newHandle.type = 1;
  84. m_hPorts.push_back(newHandle);
  85. }
  86. else
  87. {
  88. //端口打印机没有连接,那么就直接关闭掉并口,避免占用
  89. CloseHandle(hPort);
  90. }
  91. }
  92. void CPosPrinter::InitBingkou()
  93. {
  94. std::wstring LptStr = L"lpt1";
  95. HANDLE hPort = CreateFile(LptStr.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
  96. if(hPort == INVALID_HANDLE_VALUE)
  97. {
  98. DWORD error = GetLastError();
  99. if(error == 2)
  100. {
  101. //没有指定的文件
  102. LOG_INFO("本机器没有并口!");
  103. }
  104. else if(error == 5)
  105. {
  106. LOG_INFO("并口被占用!");
  107. }
  108. }
  109. else
  110. {
  111. //这个表示并口可以使用
  112. LOG_INFO("找到并口,准备进行打印机检测! hPort:" << hPort);
  113. if(PortTest(hPort) == true)
  114. {
  115. //并口测试连通,保存起来
  116. PrinterHandle newHandle;
  117. newHandle.hPort = hPort;
  118. newHandle.type = 2;
  119. m_hPorts.push_back(newHandle);
  120. }
  121. else
  122. {
  123. //并口打印机没有连接,那么就直接关闭掉并口,避免占用
  124. CloseHandle(hPort);
  125. }
  126. }
  127. }
  128. void CPosPrinter::InitCom()
  129. {
  130. CComHelper helper;
  131. std::vector<std::wstring> comVector = helper.getComPort();
  132. for(std::vector<std::wstring>::iterator it = comVector.begin(); it != comVector.end(); it++)
  133. {
  134. std::wstring com2Str = *it;
  135. HANDLE hPort = CreateFile(com2Str.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  136. if(hPort == INVALID_HANDLE_VALUE)
  137. {
  138. DWORD error = GetLastError();
  139. if(error == 2)
  140. {
  141. //没有指定的文件
  142. LOG_INFO("没有找到对应的串口 " << com2Str.c_str());
  143. }
  144. else if(error == 5)
  145. {
  146. LOG_INFO("串口被占用 " << com2Str.c_str());
  147. }
  148. }
  149. else
  150. {
  151. LOG_INFO(com2Str.c_str() << " success, handle:" << hPort);
  152. //扎到了可用的串口,设置串口波特率
  153. DCB dcb;
  154. dcb.DCBlength = sizeof(dcb);
  155. GetCommState(hPort, &dcb);
  156. //佳博的串口打印机,默认是这个波特率
  157. dcb.BaudRate = 19200;
  158. if(!SetCommState(hPort, &dcb))
  159. {
  160. LOG_INFO("set baudRate failed!");
  161. CloseHandle(hPort);
  162. continue;
  163. }
  164. //设定通讯端口超时参数
  165. COMMTIMEOUTS tmouts;
  166. tmouts.ReadIntervalTimeout = 100;
  167. tmouts.ReadTotalTimeoutMultiplier = 100;
  168. tmouts.ReadTotalTimeoutConstant = 100;
  169. tmouts.WriteTotalTimeoutConstant = 100;
  170. tmouts.WriteTotalTimeoutMultiplier = 100;
  171. SetCommTimeouts(hPort, &tmouts);
  172. //设置端口缓冲
  173. SetupComm(hPort, 1024, 1024);
  174. //清除通讯端口缓存
  175. PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT);
  176. //保存端口
  177. PrinterHandle newHandle;
  178. newHandle.hPort = hPort;
  179. newHandle.type = 3;
  180. m_hPorts.push_back(newHandle);
  181. }
  182. }
  183. }
  184. /*
  185. *找到所有可用的小票打印机,包括USB、并口、串口3个类型,注意这里不包含网口
  186. **/
  187. void CPosPrinter::InitShouyin()
  188. {
  189. //开始添加usb
  190. InitUsb();
  191. //开始添加并口的端口
  192. InitBingkou();
  193. //智能识别模式不再自动处理串口,串口的需要人工去选择类型
  194. //InitCom();
  195. }
  196. /*
  197. *获取CreateFile的USB端口号
  198. **/
  199. int CPosPrinter::GetDevicePath(LPGUID lpGuid, int usbType)
  200. {
  201. HDEVINFO hDevInfoSet;
  202. SP_DEVINFO_DATA spDevInfoData;
  203. SP_DEVICE_INTERFACE_DATA ifData;
  204. PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
  205. int nCount;
  206. int nTotle;
  207. BOOL bResult;
  208. //这2个字符串,用于根据usb的名字对比是否为打印机设备
  209. wstring strUSBPrint = TEXT("USB 打印支持");
  210. //xp上是英文
  211. wstring strUSBPrint_EN = L"USB Printing Support";
  212. // 取得一个该GUID相关的设备信息集句柄
  213. hDevInfoSet = ::SetupDiGetClassDevs(lpGuid, // class GUID
  214. NULL, // 无关键字
  215. NULL, // 不指定父窗口句柄
  216. DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
  217. // 失败...
  218. if(hDevInfoSet == INVALID_HANDLE_VALUE)
  219. {
  220. LOG_INFO("SetupDiGetClassDevs failed \r\n");
  221. return 0;
  222. }
  223. // 申请设备接口数据空间
  224. pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
  225. pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  226. nTotle = -1;
  227. nCount = 0;
  228. bResult = TRUE;
  229. // 设备序号=0,1,2... 逐一测试设备接口,到失败为止
  230. while(bResult)
  231. {
  232. nTotle++;
  233. spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  234. // 枚举符合该GUID的设备接口
  235. bResult = ::SetupDiEnumDeviceInfo(
  236. hDevInfoSet, // 设备信息集句柄
  237. (ULONG)nTotle, // 设备信息集里的设备序号
  238. &spDevInfoData); // 设备接口信息
  239. if(bResult)
  240. {
  241. DWORD DataT;
  242. TCHAR buf[MAX_PATH] = { 0 };
  243. DWORD nSize = 0;
  244. // get Friendly Name or Device Description
  245. if(SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
  246. SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize))
  247. {
  248. }
  249. else if(SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
  250. SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize))
  251. {
  252. }
  253. else
  254. {
  255. lstrcpy(buf, _T("Unknown"));
  256. }
  257. wstring ws_buf = buf;
  258. //是否是要找的设备类型
  259. if(ws_buf != strUSBPrint && ws_buf != strUSBPrint_EN)
  260. {
  261. LOG_INFO("not good usb, buf:" << CLewaimaiString::UnicodeToANSI(ws_buf).c_str());
  262. continue;
  263. }
  264. LOG_INFO("good usb, buf:" << CLewaimaiString::UnicodeToANSI(ws_buf).c_str());
  265. ifData.cbSize = sizeof(ifData);
  266. // 枚舉符合該GUID的設備接口
  267. bResult = ::SetupDiEnumDeviceInterfaces(
  268. hDevInfoSet, // 設備信息集句柄
  269. NULL, // 不需額外的設備描述
  270. lpGuid, // GUID
  271. (ULONG)nTotle, // 設備信息集里的設備序號
  272. &ifData); // 設備接口信息
  273. if(bResult)
  274. {
  275. // 取得该设备接口的细节(设备路径)
  276. bResult = SetupDiGetInterfaceDeviceDetail(
  277. hDevInfoSet, // 设备信息集句柄
  278. &ifData, // 设备接口信息
  279. pDetail, // 设备接口细节(设备路径)
  280. INTERFACE_DETAIL_SIZE, // 输出缓冲区大小
  281. NULL, // 不需计算输出缓冲区大小(直接用设定值)
  282. NULL); // 不需额外的设备描述
  283. if(bResult)
  284. {
  285. wstring DevicePath = pDetail->DevicePath;
  286. wstring vid = DevicePath.substr(DevicePath.find(_T("vid_"), 0) + 4, 4);
  287. wstring pid = DevicePath.substr(DevicePath.find(_T("pid_"), 0) + 4, 4);
  288. LOG_INFO("Vid:" << vid.c_str() << ", Pid:" << pid.c_str());
  289. if(usbType == 1 && GetPrinterType(vid, pid) == 2)
  290. {
  291. //标签打印机,暂时不处理打印
  292. LOG_INFO("标签打印机,暂时不打印!");
  293. continue;
  294. }
  295. // 复制设备路径到输出缓冲区
  296. m_usb_devices.push_back(DevicePath);
  297. // 调整计数值
  298. nCount++;
  299. LOG_INFO("Cnt = " << nCount << ",pDetail->DevicePath =" << pDetail->DevicePath);
  300. }
  301. }
  302. }
  303. else
  304. {
  305. //LOG_INFO("SetupDiEnumDeviceInfo FAILED!@");
  306. }
  307. }
  308. // 释放设备接口数据空间
  309. ::GlobalFree(pDetail);
  310. // 关闭设备信息集句柄
  311. ::SetupDiDestroyDeviceInfoList(hDevInfoSet);
  312. return nCount;
  313. }
  314. /*
  315. *返回打印机的类型, 1:普通热敏打印机 2:标签打印机
  316. **/
  317. int CPosPrinter::GetPrinterType(wstring vid, wstring pid)
  318. {
  319. if(vid == L"6868" && pid == L"0500")
  320. {
  321. //佳博标签打印机
  322. return 2;
  323. }
  324. return 1;
  325. }
  326. /*
  327. *打印收银小票
  328. **/
  329. void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
  330. {
  331. //设置模式,后面输出数据不会错
  332. m_type = 1;
  333. std::string printer_leixing = CSetting::GetParam("setting_printer_leixing");
  334. if(printer_leixing == "auto")
  335. {
  336. InitShouyin();
  337. }
  338. else if(printer_leixing == "usb")
  339. {
  340. std::string printer_usb = CSetting::GetParam("setting_printer_usb");
  341. std::wstring ws_printer_usb = CLewaimaiString::UTF8ToUnicode(printer_usb);
  342. InitOneUsb(ws_printer_usb);
  343. }
  344. else if(printer_leixing == "bingkou")
  345. {
  346. InitBingkou();
  347. }
  348. else if(printer_leixing == "chuankou")
  349. {
  350. InitCom();
  351. }
  352. else if(printer_leixing == "wangkou")
  353. {
  354. m_type = 2;
  355. std::string wangkou_ip = CSetting::GetParam("setting_printer_wangkou_ip");
  356. //初始化连接
  357. try
  358. {
  359. boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(wangkou_ip.c_str()), 9100);
  360. m_socket.connect(ep);
  361. }
  362. catch(std::exception& e)
  363. {
  364. std::string err = e.what();
  365. LOG_INFO("打印机失败,IP地址:" << wangkou_ip.c_str() << ",错误信息:" << err.c_str());
  366. }
  367. }
  368. //读取当前收银打印机的设置
  369. std::string guige = CSetting::GetParam("setting_printer_guige");
  370. std::string lianshu = CSetting::GetParam("setting_printer_lianshu");
  371. int n_lianshu = atoi(lianshu.c_str());
  372. //正式开始打印
  373. for(int i = 0; i < n_lianshu; i++)
  374. {
  375. POS_Reset();
  376. string shop_name = "#" + order.m_restaurant_number + " " + CLewaimaiString::UTF8ToANSI(order.m_shop_name);
  377. POS_TextOut(shop_name, true, true, 1);
  378. POS_FeedLine();
  379. POS_FeedLine();
  380. bool setting_printer_quhuo_big = false;
  381. if(CSetting::GetParam("setting_printer_quhuo_big") == "1")
  382. {
  383. setting_printer_quhuo_big = true;
  384. }
  385. if(order.m_is_selftake == "1")
  386. {
  387. POS_TextOut("到店自取订单", false, setting_printer_quhuo_big, 1);
  388. POS_FeedLine();
  389. POS_FeedLine();
  390. }
  391. else
  392. {
  393. POS_TextOut("外卖订单", false, setting_printer_quhuo_big, 1);
  394. POS_FeedLine();
  395. }
  396. POS_FeedLine();
  397. //订单来源
  398. string from_type = "订单来源:" + CLewaimaiString::UTF8ToANSI(order.m_from_type);
  399. POS_TextOut(from_type);
  400. POS_FeedLine();
  401. //订单号
  402. bool setting_printer_dingdanhao_big = false;
  403. if(CSetting::GetParam("setting_printer_dingdanhao_big") == "1")
  404. {
  405. setting_printer_dingdanhao_big = true;
  406. }
  407. string order_num = "订 单 号:" + CLewaimaiString::UTF8ToANSI(order.m_order_num);
  408. POS_TextOut(order_num, false, setting_printer_dingdanhao_big);
  409. POS_FeedLine();
  410. //下单时间
  411. bool setting_printer_xiadanshijian_big = false;
  412. if(CSetting::GetParam("setting_printer_xiadanshijian_big") == "1")
  413. {
  414. setting_printer_xiadanshijian_big = true;
  415. }
  416. string order_date = "下单时间:" + CLewaimaiString::UTF8ToANSI(order.m_order_date);
  417. POS_TextOut(order_date, false, setting_printer_xiadanshijian_big);
  418. POS_FeedLine();
  419. //配送时间
  420. bool setting_printer_peisongshijian_big = false;
  421. if(CSetting::GetParam("setting_printer_peisongshijian_big") == "1")
  422. {
  423. setting_printer_peisongshijian_big = true;
  424. }
  425. if(order.m_is_selftake == "1")
  426. {
  427. string date = "自取时间:" + CLewaimaiString::UTF8ToANSI(order.m_delivery_date);
  428. POS_TextOut(date, false, setting_printer_peisongshijian_big);
  429. POS_FeedLine();
  430. }
  431. else
  432. {
  433. string date = "配送时间:" + CLewaimaiString::UTF8ToANSI(order.m_delivery_date);
  434. POS_TextOut(date, false, setting_printer_peisongshijian_big);
  435. POS_FeedLine();
  436. }
  437. //姓名
  438. bool setting_printer_name_big = false;
  439. if(CSetting::GetParam("setting_printer_name_big") == "1")
  440. {
  441. setting_printer_name_big = true;
  442. }
  443. if(order.m_is_selftake != "1")
  444. {
  445. string name = "姓名:" + CLewaimaiString::UTF8ToANSI(order.m_customer_name);
  446. POS_TextOut(name, false, setting_printer_name_big);
  447. POS_FeedLine();
  448. }
  449. //电话
  450. bool setting_printer_phone_big = false;
  451. if(CSetting::GetParam("setting_printer_phone_big") == "1")
  452. {
  453. setting_printer_phone_big = true;
  454. }
  455. string phone = "电话:" + CLewaimaiString::UTF8ToANSI(order.m_phone);
  456. POS_TextOut(phone, false, setting_printer_phone_big);
  457. POS_FeedLine();
  458. //地址
  459. bool setting_printer_address_big = false;
  460. if(CSetting::GetParam("setting_printer_address_big") == "1")
  461. {
  462. setting_printer_address_big = true;
  463. }
  464. if(order.m_is_selftake != "1")
  465. {
  466. string address = "地址:" + CLewaimaiString::UTF8ToANSI(order.m_address);
  467. POS_TextOut(address, false, setting_printer_address_big);
  468. POS_FeedLine();
  469. }
  470. //预设选项
  471. if(order.m_order_field.size() > 1)
  472. {
  473. for(std::vector<CWaimaiOrderField>::iterator it = order.m_order_field.begin(); it != order.m_order_field.end() - 1; it++)
  474. {
  475. string order_field = CLewaimaiString::UTF8ToANSI((*it).name) + ":" + CLewaimaiString::UTF8ToANSI((*it).value);
  476. POS_TextOut(order_field, false, false, 0);
  477. POS_FeedLine();
  478. }
  479. }
  480. //准备开始打印商品详情
  481. string lines;
  482. if(guige == "58")
  483. {
  484. lines = "--------------------------------";
  485. }
  486. else
  487. {
  488. lines = "------------------------------------------------";
  489. }
  490. POS_TextOut(lines);
  491. POS_FeedLine();
  492. //商品标题
  493. bool setting_printer_shangpin_big = false;
  494. if(CSetting::GetParam("setting_printer_shangpin_big") == "1")
  495. {
  496. setting_printer_shangpin_big = true;
  497. }
  498. if(guige == "58")
  499. {
  500. POS_TextOut("商品 单价 数量 金额", false, setting_printer_shangpin_big);
  501. }
  502. else
  503. {
  504. POS_TextOut("商品 单价 数量 金额", false, setting_printer_shangpin_big);
  505. }
  506. POS_FeedLine();
  507. //商品内容
  508. for(std::vector<CWaimaiOrderItem>::iterator it = order.m_order_items.begin(); it != order.m_order_items.end(); it++)
  509. {
  510. std::string food_name = (*it).m_food_name;
  511. std::string food_price = (*it).m_item_price;
  512. std::string quantity = (*it).m_quantity;
  513. //计算总价
  514. double item_price = atof(food_price.c_str()) * atof(quantity.c_str());
  515. std::string food_total_price = CLewaimaiString::DoubleToString(item_price, 2);
  516. food_name = CLewaimaiString::UTF8ToANSI(food_name);
  517. //先输出商品名字
  518. std::vector<string> m_names;
  519. if(guige == "58")
  520. {
  521. m_names = HandleFoodname(food_name, 1);
  522. }
  523. else
  524. {
  525. m_names = HandleFoodname(food_name, 2);
  526. }
  527. std::string firstLine = m_names[0];
  528. int nGuige;
  529. if(guige == "58")
  530. {
  531. nGuige = 1;
  532. }
  533. else
  534. {
  535. nGuige = 2;
  536. }
  537. std::string priceShow = HandleFoodItemPrice(food_price, nGuige);
  538. std::string quantityShow = HandleFoodQuantity(quantity, nGuige);
  539. std::string priceTotalShow = HandleFoodTotalPrice(food_total_price, nGuige);
  540. std::string firstLineShow = firstLine + priceShow + quantityShow + priceTotalShow;
  541. POS_TextOut(firstLineShow, false, setting_printer_shangpin_big);
  542. POS_FeedLine();
  543. for(std::vector<string>::iterator it = m_names.begin() + 1; it != m_names.end(); it++)
  544. {
  545. POS_TextOut((*it), false, setting_printer_shangpin_big);
  546. POS_FeedLine();
  547. }
  548. }
  549. //判断是否有备注
  550. if(order.m_memo.length() > 0)
  551. {
  552. bool setting_printer_memo_big = false;
  553. if(CSetting::GetParam("setting_printer_memo_big") == "1")
  554. {
  555. setting_printer_memo_big = true;
  556. }
  557. POS_FeedLine();
  558. string address = "顾客备注:" + CLewaimaiString::UTF8ToANSI(order.m_memo);
  559. POS_TextOut(address, false, setting_printer_memo_big);
  560. POS_FeedLine();
  561. }
  562. //结束商品详情打印
  563. POS_TextOut(lines);
  564. POS_FeedLine();
  565. //开始打印其他的费用
  566. bool is_other_money = false;
  567. bool setting_printer_price_big = false;
  568. if(CSetting::GetParam("setting_printer_price_big") == "1")
  569. {
  570. setting_printer_price_big = true;
  571. }
  572. if(order.m_delivery > 0)
  573. {
  574. string delivery = "配送费:" + CLewaimaiString::DoubleToString((double)order.m_delivery, 2);
  575. POS_TextOut(delivery, false, setting_printer_price_big);
  576. POS_FeedLine();
  577. is_other_money = true;
  578. }
  579. if(order.m_is_dabao == "1")
  580. {
  581. string dabao = "打包费:" + CLewaimaiString::UTF8ToANSI(order.m_dabao_money);
  582. POS_TextOut(dabao, false, setting_printer_price_big);
  583. POS_FeedLine();
  584. is_other_money = true;
  585. }
  586. //开始显示增值服务费
  587. if(order.m_addservie.size() > 0)
  588. {
  589. for(std::vector<CWaimaiOrderField>::iterator it = order.m_addservie.begin(); it != order.m_addservie.end(); it++)
  590. {
  591. string addservice = CLewaimaiString::UTF8ToANSI((*it).name) + ":" + CLewaimaiString::DoubleToString((double)atof((*it).value.c_str()), 2);
  592. POS_TextOut(addservice, false, setting_printer_price_big);
  593. POS_FeedLine();
  594. is_other_money = true;
  595. }
  596. is_other_money = true;
  597. }
  598. if(order.m_discount < 10)
  599. {
  600. string discount = "打折:" + CLewaimaiString::DoubleToString((double)order.m_discount, 2) + "折";
  601. POS_TextOut(discount, false, setting_printer_price_big);
  602. POS_FeedLine();
  603. is_other_money = true;
  604. }
  605. if(order.m_is_member_discount == "1")
  606. {
  607. string member_discount = "会员优惠:-" + order.m_member_discount;
  608. POS_TextOut(member_discount, false, setting_printer_price_big);
  609. POS_FeedLine();
  610. is_other_money = true;
  611. }
  612. if(order.m_is_firstcut == "1")
  613. {
  614. string firstcut = "首单优惠:-" + order.m_firstcut_value;
  615. POS_TextOut(firstcut, false, setting_printer_price_big);
  616. POS_FeedLine();
  617. is_other_money = true;
  618. }
  619. //满减
  620. string::size_type position = order.m_promotion.find(":");
  621. if(position != order.m_promotion.npos)
  622. {
  623. string promotion_value;
  624. promotion_value.assign(order.m_promotion, position + 1);
  625. string promotion = "满减优惠:-" + CLewaimaiString::DoubleToString((double)(atof(promotion_value.c_str())), 2);
  626. POS_TextOut(promotion, false, setting_printer_price_big);
  627. POS_FeedLine();
  628. is_other_money = true;
  629. }
  630. if(order.m_coupon > 0)
  631. {
  632. string coupon = "优惠券:-" + CLewaimaiString::DoubleToString((double)order.m_coupon, 2);
  633. POS_TextOut(coupon, false, setting_printer_price_big);
  634. POS_FeedLine();
  635. is_other_money = true;
  636. }
  637. if(is_other_money)
  638. {
  639. POS_TextOut(lines);
  640. POS_FeedLine();
  641. }
  642. //最后显示总价
  643. POS_TextOut("总计:¥" + CLewaimaiString::DoubleToString(order.m_price, 2), false, setting_printer_price_big, 2);
  644. POS_FeedLine();
  645. //显示付款方式
  646. bool setting_printer_pay_big = false;
  647. if(CSetting::GetParam("setting_printer_pay_big") == "1")
  648. {
  649. setting_printer_pay_big = true;
  650. }
  651. POS_TextOut("支付方式:" + CLewaimaiString::UTF8ToANSI(order.m_pay_type), false, setting_printer_pay_big, 2);
  652. POS_FeedLine();
  653. //准备开始打印二维码
  654. std::string order_no = order.m_order_no;
  655. order_no = CLewaimaiString::UTF8ToANSI(order_no);
  656. CBitmapHelper helper;
  657. helper.LoadImage(L"D:\\800.bmp");
  658. Bitmap* bmp = helper.getBmp();
  659. //先进行图片预处理
  660. unsigned int nWidth = bmp->GetWidth();
  661. unsigned int nHeight = bmp->GetHeight();
  662. //压缩尺寸
  663. if (nWidth > 380)
  664. {
  665. int newWidth = 380;
  666. int newHeight = (int)(nHeight / (nWidth / 380.0));
  667. helper.ScaleBitmap(newWidth, newHeight);;
  668. }
  669. //二值化
  670. helper.Image2Values();
  671. PrintBmp(helper.getBmp());
  672. //走纸几行再切
  673. POS_FeedLine();
  674. POS_FeedLine();
  675. POS_FeedLine();
  676. POS_FeedLine();
  677. POS_FeedLine();
  678. POS_CutPaper();
  679. }
  680. //还原打印机初始设置,有些傻逼收银设备居然不是自动调用,比如哗啦啦
  681. POS_Reset();
  682. //关闭设备
  683. for(std::vector<PrinterHandle>::iterator it = m_hPorts.begin(); it != m_hPorts.end(); it++)
  684. {
  685. CloseHandle((*it).hPort);
  686. }
  687. }
  688. void CPosPrinter::PrintWaimaiOrderBiaoqian(CWaimaiOrder& order)
  689. {
  690. m_type = 1;
  691. std::string printer_usb = CSetting::GetParam("setting_biaoqian_printer_usb");
  692. std::wstring ws_printer_usb = CLewaimaiString::UTF8ToUnicode(printer_usb);
  693. //连接usb端口
  694. InitOneUsb(ws_printer_usb);
  695. //初始化标签打印机
  696. BIAOQIAN_Reset();
  697. std::vector<CWaimaiOrderItem> cur_printer_use = order.m_order_items;
  698. //先计算商品的总数量
  699. int foodNum = 0;
  700. for(std::vector<CWaimaiOrderItem>::iterator it = cur_printer_use.begin(); it != cur_printer_use.end(); it++)
  701. {
  702. std::string quantity = (*it).m_quantity;
  703. foodNum += atoi(quantity.c_str());
  704. }
  705. //商品内容
  706. int curFoodNum = 0;
  707. for(std::vector<CWaimaiOrderItem>::iterator it = cur_printer_use.begin(); it != cur_printer_use.end(); it++)
  708. {
  709. std::string food_name = (*it).m_food_name;
  710. std::string food_price = (*it).m_item_price;
  711. std::string quantity = (*it).m_quantity;
  712. //每份商品打印一个标签
  713. int nQuantity = atoi(quantity.c_str());
  714. for(int i = 0; i < nQuantity; i++)
  715. {
  716. curFoodNum++;
  717. std::string restaurant_number = order.m_restaurant_number;
  718. std::string order_num_info = "外卖 #" + CLewaimaiString::UTF8ToANSI(restaurant_number);
  719. BIAOQIAN_TEXTOUT(order_num_info, 16, 16, 1, 1);
  720. //打印份数
  721. std::string numInfo = to_string(curFoodNum) + "/" + to_string(foodNum);
  722. BIAOQIAN_TEXTOUT(numInfo, 160, 16, 1, 1);
  723. //每行最多显示12个汉字,这里要计算一下换行(要先转成ANSI格式)
  724. std::string handle_food_name = CLewaimaiString::UTF8ToANSI(food_name);
  725. std::vector<std::string> foodNameVector = HandleBiaoqianFoodname(handle_food_name);
  726. int nRow = 0;
  727. //考虑是否用大号字体
  728. bool is_big_name = false;
  729. if(foodNameVector.size() <= 2)
  730. {
  731. //不超过2行,可以用大的字体
  732. is_big_name = true;
  733. }
  734. LOG_INFO("foodNameVector size:" << foodNameVector.size());
  735. for(std::vector<std::string>::iterator it = foodNameVector.begin(); it != foodNameVector.end(); it++)
  736. {
  737. LOG_INFO("nRow:" << nRow << ", 准备打印商品名字:" << (*it).c_str());
  738. if(is_big_name)
  739. {
  740. BIAOQIAN_TEXTOUT(*it, 16, 56 + 64 * nRow, 1, 2);
  741. }
  742. else
  743. {
  744. BIAOQIAN_TEXTOUT(*it, 16, 56 + 32 * nRow, 1, 1);
  745. }
  746. nRow++;
  747. }
  748. //打印价格
  749. std::string priceInfo = CLewaimaiString::UTF8ToANSI(food_price) + "元";
  750. BIAOQIAN_TEXTOUT(priceInfo, 16, 180, 1, 1);
  751. //打印订单号
  752. std::string order_num = "订单号:" + CLewaimaiString::UTF8ToANSI(order.m_order_num);
  753. BIAOQIAN_TEXTOUT(order_num, 16, 210, 1, 1);
  754. BIAOQIAN_PRINT();
  755. BIAOQIAN_CLS();
  756. }
  757. }
  758. }
  759. void CPosPrinter::PrintWaimaiOrderChufang(CWaimaiOrder& order)
  760. {
  761. //设置模式,后面输出数据不会错
  762. m_type = 2;
  763. //读取厨房打印机信息
  764. std::vector<ChufangPrinter> total_printers = CSetting::getChufangPrints();
  765. for(std::vector<ChufangPrinter>::iterator it = total_printers.begin(); it != total_printers.end(); it++)
  766. {
  767. ChufangPrinter printer = *it;
  768. std::string ip = printer.ip;
  769. //初始化连接
  770. try
  771. {
  772. boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(ip.c_str()), 9100);
  773. m_socket.connect(ep);
  774. }
  775. catch(std::exception& e)
  776. {
  777. std::string err = e.what();
  778. LOG_INFO("连接厨房打印机失败,IP地址:" << ip.c_str() << ",错误信息:" << err.c_str());
  779. //连接失败了,处理下一个厨房打印机
  780. continue;
  781. }
  782. std::string guige = printer.guige;
  783. std::string fendan = printer.fendan;
  784. std::vector<CWaimaiOrderItem> cur_printer_use = order.m_order_items;
  785. if(fendan == "0")
  786. {
  787. POS_Reset();
  788. POS_TextOut("派工单", true, true, 1);
  789. POS_FeedLine();
  790. POS_FeedLine();
  791. string order_type = "#" + order.m_restaurant_number + " ";
  792. if(order.m_is_selftake == "1")
  793. {
  794. POS_TextOut(order_type + "到店自取订单", false, false, 1);
  795. POS_FeedLine();
  796. POS_FeedLine();
  797. }
  798. else
  799. {
  800. POS_TextOut(order_type + "外卖订单", false, false, 1);
  801. POS_FeedLine();
  802. POS_FeedLine();
  803. }
  804. //预设选项
  805. if(order.m_order_field.size() > 1)
  806. {
  807. for(std::vector<CWaimaiOrderField>::iterator it = order.m_order_field.begin(); it != order.m_order_field.end() - 1; it++)
  808. {
  809. string order_field = CLewaimaiString::UTF8ToANSI((*it).name) + ":" + CLewaimaiString::UTF8ToANSI((*it).value);
  810. POS_TextOut(order_field, false, false, 0);
  811. POS_FeedLine();
  812. }
  813. }
  814. //准备开始打印商品详情
  815. string lines;
  816. if(guige == "58")
  817. {
  818. lines = "--------------------------------";
  819. }
  820. else
  821. {
  822. lines = "------------------------------------------------";
  823. }
  824. POS_TextOut(lines);
  825. POS_FeedLine();
  826. //商品标题
  827. if(guige == "58")
  828. {
  829. POS_TextOut("商品 单价 数量 金额");
  830. }
  831. else
  832. {
  833. POS_TextOut("商品 单价 数量 金额");
  834. }
  835. POS_FeedLine();
  836. //商品内容
  837. for(std::vector<CWaimaiOrderItem>::iterator it = cur_printer_use.begin(); it != cur_printer_use.end(); it++)
  838. {
  839. std::string food_name = (*it).m_food_name;
  840. std::string food_price = (*it).m_item_price;
  841. std::string quantity = (*it).m_quantity;
  842. //计算总价
  843. double item_price = atof(food_price.c_str()) * atof(quantity.c_str());
  844. std::string food_total_price = CLewaimaiString::DoubleToString(item_price, 2);
  845. food_name = CLewaimaiString::UTF8ToANSI(food_name);
  846. //先输出商品名字
  847. std::vector<string> m_names;
  848. if(guige == "58")
  849. {
  850. m_names = HandleFoodname(food_name, 1);
  851. }
  852. else
  853. {
  854. m_names = HandleFoodname(food_name, 2);
  855. }
  856. std::string firstLine = m_names[0];
  857. int nGuige;
  858. if(guige == "58")
  859. {
  860. nGuige = 1;
  861. }
  862. else
  863. {
  864. nGuige = 2;
  865. }
  866. std::string priceShow = HandleFoodItemPrice(food_price, nGuige);
  867. std::string quantityShow = HandleFoodQuantity(quantity, nGuige);
  868. std::string priceTotalShow = HandleFoodTotalPrice(food_total_price, nGuige);
  869. std::string firstLineShow = firstLine + priceShow + quantityShow + priceTotalShow;
  870. POS_TextOut(firstLineShow, false, false, 0);
  871. POS_FeedLine();
  872. for(std::vector<string>::iterator it = m_names.begin() + 1; it != m_names.end(); it++)
  873. {
  874. POS_TextOut((*it), false, false, 0);
  875. POS_FeedLine();
  876. }
  877. }
  878. //判断是否有备注
  879. if(order.m_memo.length() > 0)
  880. {
  881. POS_FeedLine();
  882. string address = "顾客备注:" + CLewaimaiString::UTF8ToANSI(order.m_memo);
  883. POS_TextOut(address, false, false, 0);
  884. POS_FeedLine();
  885. }
  886. //结束商品详情打印
  887. POS_TextOut(lines);
  888. POS_FeedLine();
  889. POS_FeedLine();
  890. POS_FeedLine();
  891. POS_FeedLine();
  892. POS_FeedLine();
  893. POS_FeedLine();
  894. POS_CutPaper();
  895. //还原打印机初始设置,有些傻逼收银设备居然不是自动调用,比如哗啦啦
  896. POS_Reset();
  897. }
  898. else
  899. {
  900. POS_Reset();
  901. //分单模式下,每个商品打印一张单
  902. for(std::vector<CWaimaiOrderItem>::iterator it = cur_printer_use.begin(); it != cur_printer_use.end(); it++)
  903. {
  904. POS_TextOut("派工单", true, true, 1);
  905. POS_FeedLine();
  906. POS_FeedLine();
  907. string order_type = "#" + order.m_restaurant_number + " ";
  908. if(order.m_is_selftake == "1")
  909. {
  910. POS_TextOut(order_type + "到店自取订单", false, false, 1);
  911. POS_FeedLine();
  912. POS_FeedLine();
  913. }
  914. else
  915. {
  916. POS_TextOut(order_type + "外卖订单", false, false, 1);
  917. POS_FeedLine();
  918. POS_FeedLine();
  919. }
  920. //预设选项
  921. if(order.m_order_field.size() > 1)
  922. {
  923. for(std::vector<CWaimaiOrderField>::iterator it = order.m_order_field.begin(); it != order.m_order_field.end() - 1; it++)
  924. {
  925. string order_field = CLewaimaiString::UTF8ToANSI((*it).name) + ":" + CLewaimaiString::UTF8ToANSI((*it).value);
  926. POS_TextOut(order_field, false, false, 0);
  927. POS_FeedLine();
  928. }
  929. }
  930. //准备开始打印商品详情
  931. string lines;
  932. if(guige == "58")
  933. {
  934. lines = "--------------------------------";
  935. }
  936. else
  937. {
  938. lines = "------------------------------------------------";
  939. }
  940. POS_TextOut(lines);
  941. POS_FeedLine();
  942. //商品标题
  943. if(guige == "58")
  944. {
  945. POS_TextOut("商品 单价 数量 金额");
  946. }
  947. else
  948. {
  949. POS_TextOut("商品 单价 数量 金额");
  950. }
  951. POS_FeedLine();
  952. std::string food_name = (*it).m_food_name;
  953. std::string food_price = (*it).m_item_price;
  954. std::string quantity = (*it).m_quantity;
  955. //计算总价
  956. double item_price = atof(food_price.c_str()) * atof(quantity.c_str());
  957. std::string food_total_price = CLewaimaiString::DoubleToString(item_price, 2);
  958. food_name = CLewaimaiString::UTF8ToANSI(food_name);
  959. //先输出商品名字
  960. std::vector<string> m_names;
  961. if(guige == "58")
  962. {
  963. m_names = HandleFoodname(food_name, 1);
  964. }
  965. else
  966. {
  967. m_names = HandleFoodname(food_name, 2);
  968. }
  969. std::string firstLine = m_names[0];
  970. std::string priceShow = HandleFoodItemPrice(food_price, 2);
  971. std::string quantityShow = HandleFoodQuantity(quantity, 2);
  972. std::string priceTotalShow = HandleFoodTotalPrice(food_total_price, 2);
  973. std::string firstLineShow = firstLine + priceShow + quantityShow + priceTotalShow;
  974. POS_TextOut(firstLineShow, false, false, 0);
  975. POS_FeedLine();
  976. for(std::vector<string>::iterator it = m_names.begin() + 1; it != m_names.end(); it++)
  977. {
  978. POS_TextOut((*it), false, false, 0);
  979. POS_FeedLine();
  980. }
  981. //判断是否有备注
  982. if(order.m_memo.length() > 0)
  983. {
  984. POS_FeedLine();
  985. string address = "顾客备注:" + CLewaimaiString::UTF8ToANSI(order.m_memo);
  986. POS_TextOut(address, false, false, 0);
  987. POS_FeedLine();
  988. }
  989. //结束商品详情打印
  990. POS_TextOut(lines);
  991. POS_FeedLine();
  992. POS_FeedLine();
  993. POS_FeedLine();
  994. POS_FeedLine();
  995. POS_FeedLine();
  996. POS_FeedLine();
  997. POS_CutPaper();
  998. }
  999. //还原打印机初始设置,有些傻逼收银设备居然不是自动调用,比如哗啦啦
  1000. POS_Reset();
  1001. }
  1002. m_socket.close();
  1003. }
  1004. }
  1005. std::vector<std::wstring> CPosPrinter::getUsbDevices()
  1006. {
  1007. return m_usb_devices;
  1008. }
  1009. int CPosPrinter::WriteData(string msg)
  1010. {
  1011. return WriteBuf((unsigned char*)msg.c_str(), msg.length());
  1012. }
  1013. int CPosPrinter::WriteBuf(const unsigned char* buf, int len)
  1014. {
  1015. if(m_type == 1)
  1016. {
  1017. DWORD dwWrite;
  1018. for(std::vector<PrinterHandle>::iterator it = m_hPorts.begin(); it != m_hPorts.end(); it++)
  1019. {
  1020. HANDLE hPort = (*it).hPort;
  1021. if((*it).type == 1 || (*it).type == 3)
  1022. {
  1023. //串口,同步写数据
  1024. //LOG_INFO("before com writefile handle:" << hPort);
  1025. WriteFile(hPort, buf, len, &dwWrite, NULL);
  1026. //LOG_INFO("after com writefile handle:" << hPort);
  1027. }
  1028. else
  1029. {
  1030. //usb和并口,异步写数据
  1031. OVERLAPPED overlap;
  1032. memset(&overlap, 0, sizeof(overlap));
  1033. BOOL rc = WriteFile(hPort, buf, len, &dwWrite, &overlap);
  1034. if(rc)
  1035. {
  1036. //LOG_INFO("writefile success immediately, handle:" << hPort);
  1037. }
  1038. else
  1039. {
  1040. if(GetLastError() == ERROR_IO_PENDING)
  1041. {
  1042. //LOG_INFO("Request queued, waiting... handle:" << hPort);
  1043. WaitForSingleObject(hPort, 1000);
  1044. //LOG_INFO("Request completed, handle:" << hPort);
  1045. //计算写入了多少字节的数据
  1046. DWORD numread;
  1047. rc = GetOverlappedResult(
  1048. hPort,
  1049. &overlap,
  1050. &numread,
  1051. FALSE
  1052. );
  1053. //LOG_INFO("Write success " << numread << " bytes");
  1054. }
  1055. }
  1056. }
  1057. }
  1058. return 1;
  1059. }
  1060. else
  1061. {
  1062. try
  1063. {
  1064. m_socket.write_some(boost::asio::buffer(buf, len));
  1065. }
  1066. catch(const std::exception& e)
  1067. {
  1068. LOG_INFO(e.what());
  1069. }
  1070. return 0;
  1071. }
  1072. }
  1073. /*
  1074. *测试打印机是否连接
  1075. **/
  1076. bool CPosPrinter::PortTest(HANDLE hPort)
  1077. {
  1078. //标签打印机的查询状态指令
  1079. char chInitCode[2] = { 0x1b, 0x40};
  1080. DWORD dwWrite;
  1081. OVERLAPPED overlap;
  1082. memset(&overlap, 0, sizeof(overlap));
  1083. BOOL rc = WriteFile(hPort, chInitCode, 2, &dwWrite, &overlap);
  1084. if(rc)
  1085. {
  1086. LOG_INFO("writefile success immediately, handle:" << hPort);
  1087. return true;
  1088. }
  1089. else
  1090. {
  1091. if(GetLastError() == ERROR_IO_PENDING)
  1092. {
  1093. DWORD ret = WaitForSingleObject(hPort, 1000);
  1094. if(ret == 0)
  1095. {
  1096. LOG_INFO("printer is connect, handle:" << hPort);
  1097. return true;
  1098. }
  1099. else
  1100. {
  1101. LOG_INFO("printer is not connect, handle:" << hPort);
  1102. }
  1103. }
  1104. }
  1105. return false;
  1106. }
  1107. int CPosPrinter::POS_Reset(void)
  1108. {
  1109. unsigned char s[2] = {0x1B, 0x40};
  1110. WriteBuf(s, 2);
  1111. return 0;
  1112. }
  1113. int CPosPrinter::POS_FeedLine(void)
  1114. {
  1115. unsigned char s[1] = {0x0A};
  1116. WriteBuf(s, 1);
  1117. return 0;
  1118. }
  1119. int CPosPrinter::POS_Feed(void)
  1120. {
  1121. unsigned char s[3] = { 0x1B, 0x4A, 0x00 };
  1122. WriteBuf(s, 3);
  1123. return 0;
  1124. }
  1125. int CPosPrinter::POS_SetMotionUnit(int x, int y)
  1126. {
  1127. string s;
  1128. s = "\x1D\x50\xB4\xB4";
  1129. WriteData(s);
  1130. s = "\x1B\x53";
  1131. WriteData(s);
  1132. return 0;
  1133. }
  1134. int CPosPrinter::POS_SET_MOVE_X()
  1135. {
  1136. unsigned char s2[6] = { 0x1B, 0x44, 0x0C, 0x0E, 0x17, 0x00};
  1137. WriteBuf(s2, 6);
  1138. return 0;
  1139. }
  1140. int CPosPrinter::POS_MOVE_X()
  1141. {
  1142. unsigned char s[1] = { 0x09 };
  1143. WriteBuf(s, 1);
  1144. return 0;
  1145. }
  1146. int CPosPrinter::POS_SET_ABS_X(int x, int y)
  1147. {
  1148. unsigned char cx = (unsigned char)(x);
  1149. unsigned char cy = (unsigned char)(y);
  1150. unsigned char s1[4] = { 0x1B, 0x24, cx, cy };
  1151. WriteBuf(s1, 4);
  1152. return 0;
  1153. }
  1154. int CPosPrinter::POS_SET_PRINT_AREA(int x, int y)
  1155. {
  1156. unsigned char cx = (unsigned char)(x);
  1157. unsigned char cy = (unsigned char)(y);
  1158. unsigned char s1[4] = { 0x1D, 0x57, cx, cy };
  1159. WriteBuf(s1, 4);
  1160. return 0;
  1161. }
  1162. /*
  1163. *align_type:0 左对齐 1 居中对齐 2右对齐
  1164. **/
  1165. int CPosPrinter::POS_TextOut(string abc, bool is_double_width, bool is_double_height, int align_type)
  1166. {
  1167. if(is_double_width && is_double_height)
  1168. {
  1169. unsigned char s1[3] = { 0x1B, 0x21, 0x30 };
  1170. WriteBuf(s1, 3);
  1171. unsigned char s2[3] = { 0x1C, 0x21, 0x0c };
  1172. WriteBuf(s2, 3);
  1173. }
  1174. else if(is_double_width && !is_double_height)
  1175. {
  1176. unsigned char s1[3] = { 0x1B, 0x21, 0x20 };
  1177. WriteBuf(s1, 3);
  1178. unsigned char s2[3] = { 0x1C, 0x21, 0x04 };
  1179. WriteBuf(s2, 3);
  1180. }
  1181. else if(!is_double_width && is_double_height)
  1182. {
  1183. unsigned char s1[3] = { 0x1B, 0x21, 0x10 };
  1184. WriteBuf(s1, 3);
  1185. unsigned char s2[3] = { 0x1C, 0x21, 0x08 };
  1186. WriteBuf(s2, 3);
  1187. }
  1188. else
  1189. {
  1190. unsigned char s1[3] = { 0x1B, 0x21, 0x00 };
  1191. WriteBuf(s1, 3);
  1192. unsigned char s2[3] = { 0x1C, 0x57, 0x00 };
  1193. WriteBuf(s2, 3);
  1194. }
  1195. if(align_type == 0)
  1196. {
  1197. unsigned char s1[3] = { 0x1B, 0x61, 0x00 };
  1198. WriteBuf(s1, 3);
  1199. }
  1200. else if(align_type == 1)
  1201. {
  1202. unsigned char s1[3] = { 0x1B, 0x61, 0x01 };
  1203. WriteBuf(s1, 3);
  1204. }
  1205. else if(align_type == 2)
  1206. {
  1207. unsigned char s1[3] = { 0x1B, 0x61, 0x02 };
  1208. WriteBuf(s1, 3);
  1209. }
  1210. else
  1211. {
  1212. }
  1213. WriteData(abc);
  1214. return 0;
  1215. }
  1216. /*
  1217. *打印机切纸,直接切不走纸
  1218. **/
  1219. int CPosPrinter::POS_CutPaper()
  1220. {
  1221. unsigned char s[4] = { 0x1D, 0x56, 0x01};
  1222. WriteBuf(s, 3);
  1223. return 0;
  1224. }
  1225. /*
  1226. *先转换成ANSI格式才能传进来
  1227. **/
  1228. int CPosPrinter::POS_OutQRCode(std::string data)
  1229. {
  1230. // char QRCode1[8] = { 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x43, 0x05 };
  1231. //WriteBuf(QRCode1, 8);
  1232. //char QRCode2[8] = { 0 };
  1233. //QRCode2[0] = { 0x1d };
  1234. //QRCode2[1] = { 0x28 };
  1235. //QRCode2[2] = { 0x6b };
  1236. //int nLength = data.size();
  1237. //int pL = nLength + 3;
  1238. //char cpL = (char)pL;
  1239. //
  1240. //QRCode2[3] = cpL;
  1241. //QRCode2[4] = { 0x00 };
  1242. //QRCode2[5] = { 0x31 };
  1243. //QRCode2[6] = { 0x50 };
  1244. //QRCode2[7] = { 0x30 };
  1245. //char* datasend = new char[nLength + 8];
  1246. //memcpy_s(datasend, 8, QRCode2, 8);
  1247. //memcpy_s(datasend + 8, nLength, data.c_str(), nLength);
  1248. //WriteBuf(datasend, 8 + nLength);
  1249. //delete[] datasend;
  1250. unsigned char QRCode2[16] = { 0x1d, 0x28, 0x6b, 0x0b, 0x00, 0x31, 0x50, 0x30, 0x47, 0x70, 0x72, 0x69,
  1251. 0x6e, 0x74, 0x65, 0x72
  1252. };
  1253. WriteBuf(QRCode2, 16);
  1254. unsigned char QRCode3[8] = { 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30 };
  1255. WriteBuf(QRCode3, 8);
  1256. return 0;
  1257. }
  1258. void CPosPrinter::BIAOQIAN_Reset()
  1259. {
  1260. char endTag[3] = {0x0d, 0x0a, 0x00};
  1261. std::string size = "SIZE 40 mm, 30 mm";
  1262. size += endTag;
  1263. std::string gap = "GAP 2 mm,0 mm";
  1264. gap += endTag;
  1265. std::string speed = "SPEED 2.0";
  1266. speed += endTag;
  1267. std::string density = "DENSITY 12";
  1268. density += endTag;
  1269. std::string REFERENCE = "REFERENCE 0,0";
  1270. REFERENCE += endTag;
  1271. std::string PEER = "SET PEEL OFF";
  1272. PEER += endTag;
  1273. std::string TEAR = "SET TEAR ON";
  1274. TEAR += endTag;
  1275. std::string cls = "CLS";
  1276. cls += endTag;
  1277. std::string data = size + gap + speed + density + REFERENCE + PEER + TEAR + cls;
  1278. WriteData(data);
  1279. }
  1280. /*
  1281. *前进一张纸
  1282. **/
  1283. void CPosPrinter::BIAOQIAN_FORMFEED()
  1284. {
  1285. char endTag[3] = { 0x0d, 0x0a, 0x00 };
  1286. std::string formfeed = "FORMFEED";
  1287. formfeed += endTag;
  1288. WriteData(formfeed);
  1289. }
  1290. void CPosPrinter::BIAOQIAN_TEXTOUT(std::string content, int x, int y, int x_multiplication, int y_multiplication)
  1291. {
  1292. char endTag[3] = { 0x0d, 0x0a, 0x00 };
  1293. string text = "TEXT ";
  1294. text += to_string(x) + "," + to_string(y) + ",";
  1295. text += "\"TSS24.BF2\",";
  1296. text += to_string(0) + ",";
  1297. text += to_string(x_multiplication) + "," + to_string(y_multiplication) + ",";
  1298. text += "\"" + content + "\"";
  1299. text += endTag;
  1300. WriteData(text);
  1301. }
  1302. void CPosPrinter::BIAOQIAN_PRINT()
  1303. {
  1304. char endTag[3] = { 0x0d, 0x0a, 0x00 };
  1305. std::string print = "PRINT 1";
  1306. print += endTag;
  1307. WriteData(print);
  1308. }
  1309. void CPosPrinter::BIAOQIAN_CLS()
  1310. {
  1311. char endTag[3] = { 0x0d, 0x0a, 0x00 };
  1312. std::string cls = "CLS";
  1313. cls += endTag;
  1314. WriteData(cls);
  1315. }
  1316. void CPosPrinter::CalWord(string s, int& nHanzi, int& nZimu)
  1317. {
  1318. nHanzi = 0;
  1319. nZimu = 0;
  1320. const char* buffer = s.c_str();
  1321. while(*buffer != '\0')
  1322. {
  1323. if(!(*buffer >= 0 && *buffer <= 127))
  1324. {
  1325. //汉字
  1326. buffer++;
  1327. buffer++;
  1328. nHanzi++;
  1329. }
  1330. else
  1331. {
  1332. //字母
  1333. buffer++;
  1334. nZimu++;
  1335. }
  1336. }
  1337. }
  1338. /*
  1339. *规格 1:58mm 2:80mm
  1340. **/
  1341. std::vector<std::string>CPosPrinter::HandleFoodname(std::string oldname, int guige)
  1342. {
  1343. std::vector<std::string> newnameArray;
  1344. int nHanzi, nZimu;
  1345. CalWord(oldname, nHanzi, nZimu);
  1346. int nWidth = nHanzi * 2 + nZimu;
  1347. int maxWidth;
  1348. if(guige == 1)
  1349. {
  1350. maxWidth = 15;
  1351. }
  1352. else
  1353. {
  1354. maxWidth = 28;
  1355. }
  1356. if(nWidth <= maxWidth)
  1357. {
  1358. //对于nWidth补空格
  1359. for(int i = 0; i < maxWidth - nWidth; i++)
  1360. {
  1361. oldname += " ";
  1362. }
  1363. newnameArray.push_back(oldname);
  1364. return newnameArray;
  1365. }
  1366. //宽度大于15的情况,如果超过了,就要进行换行截取
  1367. const char* s = oldname.c_str();
  1368. int nTmp = 0;
  1369. int nTotal = 0;
  1370. while(*s != '\0')
  1371. {
  1372. if(!(*s >= 0 && *s <= 127))
  1373. {
  1374. //汉字的情况
  1375. s++;
  1376. nTmp++;
  1377. nTotal++;
  1378. s++;
  1379. nTmp++;
  1380. nTotal++;
  1381. }
  1382. else
  1383. {
  1384. //字母的情况
  1385. s++;
  1386. nTmp++;
  1387. nTotal++;
  1388. }
  1389. if(nTmp == maxWidth)
  1390. {
  1391. //这里开始要换行了
  1392. string newnameItem;
  1393. newnameItem.assign(oldname, nTotal - nTmp, nTmp);
  1394. newnameArray.push_back(newnameItem);
  1395. nTmp = 0;
  1396. }
  1397. else if(nTmp == maxWidth - 1)
  1398. {
  1399. //如果是第14个了,判断下一个是不是中文,如果是的话也要换行
  1400. if(!(*(s + 1) >= 0 && *(s + 1) <= 127))
  1401. {
  1402. //下一个是中文,也要换行了,补齐一个空格
  1403. string newnameItem;
  1404. newnameItem.assign(oldname, nTotal - nTmp, nTmp);
  1405. newnameItem += " ";
  1406. newnameArray.push_back(newnameItem);
  1407. nTmp = 0;
  1408. }
  1409. }
  1410. }
  1411. if(nTmp > 0)
  1412. {
  1413. //处理分隔后的最后一行
  1414. string newnameItem;
  1415. newnameItem.assign(oldname, nTotal - nTmp, nTmp);
  1416. for(int i = 0; i < maxWidth - nTmp; i++)
  1417. {
  1418. newnameItem += " ";
  1419. }
  1420. newnameArray.push_back(newnameItem);
  1421. }
  1422. return newnameArray;
  1423. }
  1424. std::string CPosPrinter::HandleFoodItemPrice(std::string oldprice, int guige)
  1425. {
  1426. double price = atof(oldprice.c_str());
  1427. if(price < 10.00)
  1428. {
  1429. //单位数
  1430. if(guige == 1)
  1431. {
  1432. return " " + oldprice;
  1433. }
  1434. else
  1435. {
  1436. return " " + oldprice;
  1437. }
  1438. }
  1439. else if(price > 9.99 && price < 100.00)
  1440. {
  1441. //双位数
  1442. if(guige == 1)
  1443. {
  1444. return " " + oldprice;
  1445. }
  1446. else
  1447. {
  1448. return " " + oldprice;
  1449. }
  1450. }
  1451. else if(price > 99.99 && price < 1000.00)
  1452. {
  1453. //三位数
  1454. if(guige == 1)
  1455. {
  1456. return " " + oldprice;
  1457. }
  1458. else
  1459. {
  1460. return " " + oldprice;
  1461. }
  1462. }
  1463. else
  1464. {
  1465. //四位数
  1466. if(guige == 1)
  1467. {
  1468. return " " + oldprice;
  1469. }
  1470. else
  1471. {
  1472. return " " + oldprice;
  1473. }
  1474. }
  1475. }
  1476. std::string CPosPrinter::HandleFoodQuantity(std::string oldquantity, int guige)
  1477. {
  1478. int n = atoi(oldquantity.c_str());
  1479. if(n < 10)
  1480. {
  1481. if(guige == 1)
  1482. {
  1483. return " " + oldquantity;
  1484. }
  1485. else
  1486. {
  1487. return " " + oldquantity;
  1488. }
  1489. }
  1490. else if(n >= 10 && n <= 99)
  1491. {
  1492. if(guige == 1)
  1493. {
  1494. return " " + oldquantity;
  1495. }
  1496. else
  1497. {
  1498. return " " + oldquantity;
  1499. }
  1500. }
  1501. else
  1502. {
  1503. if(guige == 1)
  1504. {
  1505. return "" + oldquantity;
  1506. }
  1507. else
  1508. {
  1509. return " " + oldquantity;
  1510. }
  1511. }
  1512. }
  1513. std::string CPosPrinter::HandleFoodTotalPrice(std::string oldprice, int guige)
  1514. {
  1515. double price = atof(oldprice.c_str());
  1516. if(price < 10.00)
  1517. {
  1518. //单位数
  1519. if(guige == 1)
  1520. {
  1521. return " " + oldprice;
  1522. }
  1523. else
  1524. {
  1525. return " " + oldprice;
  1526. }
  1527. }
  1528. else if(price > 9.99 && price < 100.00)
  1529. {
  1530. //双位数
  1531. if(guige == 1)
  1532. {
  1533. return " " + oldprice;
  1534. }
  1535. else
  1536. {
  1537. return " " + oldprice;
  1538. }
  1539. }
  1540. else if(price > 99.99 && price < 1000.00)
  1541. {
  1542. //三位数
  1543. if(guige == 1)
  1544. {
  1545. return " " + oldprice;
  1546. }
  1547. else
  1548. {
  1549. return " " + oldprice;
  1550. }
  1551. }
  1552. else
  1553. {
  1554. //四位数
  1555. if(guige == 1)
  1556. {
  1557. return " " + oldprice;
  1558. }
  1559. else
  1560. {
  1561. return " " + oldprice;
  1562. }
  1563. }
  1564. }
  1565. std::vector<std::string> CPosPrinter::HandleBiaoqianFoodname(std::string oldname)
  1566. {
  1567. std::vector<std::string> newnameArray;
  1568. int nHanzi, nZimu;
  1569. CalWord(oldname, nHanzi, nZimu);
  1570. int nWidth = nHanzi * 2 + nZimu;
  1571. //40 *30mmm的标签,宽度最大24
  1572. int maxWidth = 24;
  1573. if(nWidth <= maxWidth)
  1574. {
  1575. //对于nWidth补空格
  1576. for(int i = 0; i < maxWidth - nWidth; i++)
  1577. {
  1578. oldname += " ";
  1579. }
  1580. newnameArray.push_back(oldname);
  1581. return newnameArray;
  1582. }
  1583. //宽度大于15的情况,如果超过了,就要进行换行截取
  1584. const char* s = oldname.c_str();
  1585. int nTmp = 0;
  1586. int nTotal = 0;
  1587. while(*s != '\0')
  1588. {
  1589. if(!(*s >= 0 && *s <= 127))
  1590. {
  1591. //汉字的情况
  1592. s++;
  1593. nTmp++;
  1594. nTotal++;
  1595. s++;
  1596. nTmp++;
  1597. nTotal++;
  1598. }
  1599. else
  1600. {
  1601. //字母的情况
  1602. s++;
  1603. nTmp++;
  1604. nTotal++;
  1605. }
  1606. if(nTmp == maxWidth)
  1607. {
  1608. //这里开始要换行了
  1609. string newnameItem;
  1610. newnameItem.assign(oldname, nTotal - nTmp, nTmp);
  1611. newnameArray.push_back(newnameItem);
  1612. nTmp = 0;
  1613. }
  1614. else if(nTmp == maxWidth - 1)
  1615. {
  1616. //如果是第14个了,判断下一个是不是中文,如果是的话也要换行
  1617. if(!(*(s + 1) >= 0 && *(s + 1) <= 127))
  1618. {
  1619. //下一个是中文,也要换行了,补齐一个空格
  1620. string newnameItem;
  1621. newnameItem.assign(oldname, nTotal - nTmp, nTmp);
  1622. newnameItem += " ";
  1623. newnameArray.push_back(newnameItem);
  1624. nTmp = 0;
  1625. }
  1626. }
  1627. }
  1628. if(nTmp > 0)
  1629. {
  1630. //处理分隔后的最后一行
  1631. string newnameItem;
  1632. newnameItem.assign(oldname, nTotal - nTmp, nTmp);
  1633. for(int i = 0; i < maxWidth - nTmp; i++)
  1634. {
  1635. newnameItem += " ";
  1636. }
  1637. newnameArray.push_back(newnameItem);
  1638. }
  1639. return newnameArray;
  1640. }
  1641. void CPosPrinter::PrintBmp(Bitmap* bmp)
  1642. {
  1643. //设置行间距为0
  1644. unsigned char data[3] = { 0x1B, 0x33, 0x00 };
  1645. WriteBuf(data, 3);
  1646. //设置图像居中对齐
  1647. unsigned char data2[3] = { 0x1B, 0x61, 0x01 };
  1648. WriteBuf(data2, 3);
  1649. //选择位图模式
  1650. unsigned char escBmp[5] = { 0x1B, 0x2A, 0x21, 0x00, 0x00 };
  1651. unsigned int nWidth = bmp->GetWidth();
  1652. unsigned int nHeight = bmp->GetHeight();
  1653. escBmp[3] = (unsigned char)(nWidth % 256);
  1654. escBmp[4] = (unsigned char)(nWidth / 256);
  1655. Gdiplus::Color pixelColor;
  1656. //循环图片像素打印图片
  1657. for(unsigned int i = 0; i < (nHeight / 24 + 1); i++)
  1658. {
  1659. //设置模式为位图模式
  1660. WriteBuf(escBmp, 5);
  1661. unsigned char* dataTmp = new unsigned char[nWidth * 3];
  1662. memset(dataTmp, 0, nWidth * 3);
  1663. //循环宽
  1664. for(unsigned int j = 0; j < nWidth; j++)
  1665. {
  1666. for(unsigned int k = 0; k < 24; k++)
  1667. {
  1668. //找到有像素的区域,也就是未超出位图高度的区域
  1669. if(((i * 24) + k) < nHeight)
  1670. {
  1671. bmp->GetPixel(j, (i * 24) + k, &pixelColor);
  1672. unsigned char r = pixelColor.GetR();
  1673. if(r == 0)
  1674. {
  1675. //如果本来是黑色的像素,那么就把对应的数据位设置为1
  1676. dataTmp[j * 3 + k / 8] += (unsigned char)(128 >> (k % 8));
  1677. }
  1678. }
  1679. }
  1680. }
  1681. WriteBuf(dataTmp, nWidth * 3);
  1682. delete[] dataTmp;
  1683. }
  1684. //还原默认的行间距
  1685. unsigned char data3[2] = { 0x1B, 0x32};
  1686. WriteBuf(data3, 2);
  1687. }