service.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package service
  2. import (
  3. "fmt"
  4. "time"
  5. "wails-app/internal/dao"
  6. "wails-app/internal/global"
  7. )
  8. // EMD807 CSN SDK DLL 路径 (x64)
  9. const sdkDllPath = `D:\lq\资料\停车场 道闸 车牌识别 收费机\票机自制\打印机\EMD807嵌入式热敏票据打印模组\5、SDK指令集\Win_SDK_Demo_2023_08_14\Win_SDK_Demo_2023_08_14\lib\x64\CsnPrinterLibs.dll`
  10. type PrintService struct{}
  11. func NewPrintService() *PrintService {
  12. return &PrintService{}
  13. }
  14. // PrintTicket 打印入场小票
  15. func (s *PrintService) PrintTicket(printerID uint, lotName, channelCode, plateNo string, ticketID uint, ticketNo string) error {
  16. var printer dao.Printer
  17. if err := global.GVA_DB.First(&printer, printerID).Error; err != nil {
  18. return fmt.Errorf("打印机未配置: id=%d", printerID)
  19. }
  20. // 根据 port_name 判断连接类型
  21. var err error
  22. var srl *SerialPrinter
  23. var usbHandle uintptr
  24. useCSN := false
  25. if len(printer.PortName) >= 3 && printer.PortName[:3] == "COM" {
  26. srl, err = NewSerialPrinter(printer.PortName, printer.BaudRate)
  27. if err == nil {
  28. defer srl.Close()
  29. }
  30. } else {
  31. // USB → 使用 CSN SDK 直连
  32. err = InitCSN(sdkDllPath)
  33. if err == nil {
  34. name := printer.PortName
  35. // 如果配置的是 "USB" 或 "auto",自动枚举
  36. if name == "USB" || name == "auto" || name == "" {
  37. name = Csn_EnumUSB()
  38. if name == "" {
  39. name = printer.PortName
  40. }
  41. }
  42. // 先试 OpenUSB,失败则试 OpenPRN(Windows 打印机名)
  43. usbHandle, err = csn_OpenUSB(name)
  44. if err != nil {
  45. usbHandle, err = csn_OpenPRN(name)
  46. }
  47. if err == nil {
  48. useCSN = true
  49. defer csn_Close(usbHandle)
  50. }
  51. }
  52. if !useCSN {
  53. err = fmt.Errorf("无法连接打印机: %s", printer.PortName)
  54. }
  55. }
  56. if err != nil {
  57. global.GVA_DB.Model(&printer).Update("status", "offline")
  58. return fmt.Errorf("连接打印机失败: %w", err)
  59. }
  60. now := time.Now().Format("02-01-2006 15:04:05")
  61. slipNo := fmt.Sprintf("%d", ticketID)
  62. // ── CSN SDK 模式 ──
  63. if useCSN {
  64. csn_Reset()
  65. csn_Align(1) // 居中
  66. csn_Text("PARKING TICKET", 2, 2, 0, 0)
  67. csn_Text("", 1, 1, 0, 0)
  68. csn_Text(lotName, 1, 1, 0, 0)
  69. csn_Text("A-General Car", 1, 1, 0, 0)
  70. csn_Text("", 1, 1, 0, 0)
  71. csn_Text("PARK AT YOUR OWN RISK", 1, 1, 0, 1)
  72. csn_Text("================================", 1, 1, 0, 0)
  73. csn_Align(0) // 左对齐
  74. csn_Text("In-Time::"+now, 1, 1, 0, 0)
  75. if channelCode != "" {
  76. csn_Text("InGate::"+channelCode, 1, 1, 0, 0)
  77. }
  78. if plateNo != "" {
  79. csn_Text("Veh No::"+plateNo, 1, 1, 0, 0)
  80. }
  81. csn_Text("================================", 1, 1, 0, 0)
  82. csn_Text("Slip No::"+slipNo, 1, 1, 0, 0)
  83. csn_Text("================================", 1, 1, 0, 0)
  84. csn_Align(1) // 居中
  85. csn_FeedLine()
  86. csn_QRCode(ticketNo, 4)
  87. csn_FeedLine()
  88. csn_Text("SCAN AND PAY WITH", 1, 1, 0, 0)
  89. csn_Text("NEW THE CANADIA BANK APP", 1, 1, 0, 0)
  90. csn_FeedLines(3)
  91. csn_FullCut()
  92. global.GVA_DB.Model(&printer).Update("status", "online")
  93. return nil
  94. }
  95. // ── 串口模式(原有 ESC/POS)──
  96. write := func(data []byte) { srl.Write(data) }
  97. line32 := "================================"
  98. write(InitCmd)
  99. write(AlignCenterCmd)
  100. write(DoubleHeightCmd)
  101. write(BoldOnCmd)
  102. write(ESCPOS_Text("PARKING TICKET"))
  103. write(BoldOffCmd)
  104. write(NormalCmd)
  105. write(ESCPOS_Text(""))
  106. write(ESCPOS_Text(lotName))
  107. if len(lotName) > 32 {
  108. write(FontBCmd)
  109. write(AlignCenterCmd)
  110. write(ESCPOS_Text(lotName))
  111. write(NormalCmd)
  112. }
  113. write(ESCPOS_Text("A-General Car"))
  114. write(ESCPOS_Text(""))
  115. write(ESCPOS_Text("PARK AT YOUR OWN RISK"))
  116. write(ESCPOS_Text(line32))
  117. write(AlignLeftCmd)
  118. write(ESCPOS_Text("In-Time::" + now))
  119. if channelCode != "" {
  120. write(ESCPOS_Text("InGate::" + channelCode))
  121. }
  122. if plateNo != "" {
  123. write(ESCPOS_Text("Veh No::" + plateNo))
  124. }
  125. write(ESCPOS_Text(line32))
  126. write(ESCPOS_Text("Slip No::" + slipNo))
  127. write(ESCPOS_Text(line32))
  128. write(AlignCenterCmd)
  129. write(ESCPOS_Text(""))
  130. write(ESCPOS_QRCode(ticketNo))
  131. write(ESCPOS_Text(""))
  132. write(AlignCenterCmd)
  133. write(ESCPOS_Text("SCAN AND PAY WITH"))
  134. write(ESCPOS_Text("NEW THE CANADIA BANK APP"))
  135. write(InitCmd)
  136. write(ESCPOS_Text(""))
  137. write(ESCPOS_Text(""))
  138. write(ESCPOS_Text(""))
  139. write(CutPaperCmd)
  140. global.GVA_DB.Model(&printer).Update("status", "online")
  141. return nil
  142. }