CPosPrinter.cpp 46 KB

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