|
|
@@ -7,23 +7,18 @@ import (
|
|
|
"wails-app/internal/global"
|
|
|
)
|
|
|
|
|
|
-// EMD807 CSN SDK DLL 路径 (x64)
|
|
|
const sdkDllPath = `D:\lq\资料\停车场 道闸 车牌识别 收费机\票机自制\打印机\EMD807嵌入式热敏票据打印模组\5、SDK指令集\Win_SDK_Demo_2023_08_14\Win_SDK_Demo_2023_08_14\lib\x64\CsnPrinterLibs.dll`
|
|
|
|
|
|
type PrintService struct{}
|
|
|
|
|
|
-func NewPrintService() *PrintService {
|
|
|
- return &PrintService{}
|
|
|
-}
|
|
|
+func NewPrintService() *PrintService { return &PrintService{} }
|
|
|
|
|
|
-// PrintTicket 打印入场小票
|
|
|
func (s *PrintService) PrintTicket(printerID uint, lotName, channelCode, plateNo string, ticketID uint, ticketNo string) error {
|
|
|
var printer dao.Printer
|
|
|
if err := global.GVA_DB.First(&printer, printerID).Error; err != nil {
|
|
|
return fmt.Errorf("打印机未配置: id=%d", printerID)
|
|
|
}
|
|
|
|
|
|
- // 根据 port_name 判断连接类型
|
|
|
var err error
|
|
|
var srl *SerialPrinter
|
|
|
var usbHandle uintptr
|
|
|
@@ -35,43 +30,32 @@ func (s *PrintService) PrintTicket(printerID uint, lotName, channelCode, plateNo
|
|
|
defer srl.Close()
|
|
|
}
|
|
|
} else {
|
|
|
- // USB → 使用 CSN SDK 直连
|
|
|
err = InitCSN(sdkDllPath)
|
|
|
- if err == nil {
|
|
|
- name := printer.PortName
|
|
|
- // 如果配置的是 "USB" 或 "auto",自动枚举
|
|
|
- if name == "USB" || name == "auto" || name == "" {
|
|
|
- name = Csn_EnumUSB()
|
|
|
- if name == "" {
|
|
|
- name = printer.PortName
|
|
|
- }
|
|
|
- }
|
|
|
- // 先试 OpenUSB,失败则试 OpenPRN(Windows 打印机名)
|
|
|
- usbHandle, err = csn_OpenUSB(name)
|
|
|
- if err != nil {
|
|
|
- usbHandle, err = csn_OpenPRN(name)
|
|
|
- }
|
|
|
- if err == nil {
|
|
|
- useCSN = true
|
|
|
- defer csn_Close(usbHandle)
|
|
|
- }
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("加载 CSN DLL 失败: %w (path=%s)", err, sdkDllPath)
|
|
|
}
|
|
|
- if !useCSN {
|
|
|
- err = fmt.Errorf("无法连接打印机: %s", printer.PortName)
|
|
|
+ // 尝试 OpenUSB → OpenPRN
|
|
|
+ name := printer.PortName
|
|
|
+ if name == "USB" || name == "auto" || name == "" {
|
|
|
+ name = Csn_EnumUSB()
|
|
|
}
|
|
|
- }
|
|
|
- if err != nil {
|
|
|
- global.GVA_DB.Model(&printer).Update("status", "offline")
|
|
|
- return fmt.Errorf("连接打印机失败: %w", err)
|
|
|
+ usbHandle, err = csn_OpenUSB(name)
|
|
|
+ if err != nil {
|
|
|
+ usbHandle, err = csn_OpenPRN(name)
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("打开打印机失败: %w (name=%s)", err, name)
|
|
|
+ }
|
|
|
+ useCSN = true
|
|
|
+ defer csn_Close(usbHandle)
|
|
|
}
|
|
|
|
|
|
now := time.Now().Format("02-01-2006 15:04:05")
|
|
|
slipNo := fmt.Sprintf("%d", ticketID)
|
|
|
|
|
|
- // ── CSN SDK 模式 ──
|
|
|
if useCSN {
|
|
|
csn_Reset()
|
|
|
- csn_Align(1) // 居中
|
|
|
+ csn_Align(1)
|
|
|
csn_Text("PARKING TICKET", 2, 2, 0, 0)
|
|
|
csn_Text("", 1, 1, 0, 0)
|
|
|
csn_Text(lotName, 1, 1, 0, 0)
|
|
|
@@ -79,78 +63,45 @@ func (s *PrintService) PrintTicket(printerID uint, lotName, channelCode, plateNo
|
|
|
csn_Text("", 1, 1, 0, 0)
|
|
|
csn_Text("PARK AT YOUR OWN RISK", 1, 1, 0, 1)
|
|
|
csn_Text("================================", 1, 1, 0, 0)
|
|
|
-
|
|
|
- csn_Align(0) // 左对齐
|
|
|
+ csn_Align(0)
|
|
|
csn_Text("In-Time::"+now, 1, 1, 0, 0)
|
|
|
- if channelCode != "" {
|
|
|
- csn_Text("InGate::"+channelCode, 1, 1, 0, 0)
|
|
|
- }
|
|
|
- if plateNo != "" {
|
|
|
- csn_Text("Veh No::"+plateNo, 1, 1, 0, 0)
|
|
|
- }
|
|
|
+ if channelCode != "" { csn_Text("InGate::"+channelCode, 1, 1, 0, 0) }
|
|
|
+ if plateNo != "" { csn_Text("Veh No::"+plateNo, 1, 1, 0, 0) }
|
|
|
csn_Text("================================", 1, 1, 0, 0)
|
|
|
csn_Text("Slip No::"+slipNo, 1, 1, 0, 0)
|
|
|
csn_Text("================================", 1, 1, 0, 0)
|
|
|
-
|
|
|
- csn_Align(1) // 居中
|
|
|
+ csn_Align(1)
|
|
|
csn_FeedLine()
|
|
|
csn_QRCode(ticketNo, 4)
|
|
|
csn_FeedLine()
|
|
|
-
|
|
|
csn_Text("SCAN AND PAY WITH", 1, 1, 0, 0)
|
|
|
csn_Text("NEW THE CANADIA BANK APP", 1, 1, 0, 0)
|
|
|
csn_FeedLines(3)
|
|
|
csn_FullCut()
|
|
|
-
|
|
|
global.GVA_DB.Model(&printer).Update("status", "online")
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
- // ── 串口模式(原有 ESC/POS)──
|
|
|
+ // Serial ESC/POS fallback
|
|
|
write := func(data []byte) { srl.Write(data) }
|
|
|
line32 := "================================"
|
|
|
-
|
|
|
- write(InitCmd)
|
|
|
- write(AlignCenterCmd)
|
|
|
- write(DoubleHeightCmd)
|
|
|
- write(BoldOnCmd)
|
|
|
+ write(InitCmd); write(AlignCenterCmd); write(DoubleHeightCmd); write(BoldOnCmd)
|
|
|
write(ESCPOS_Text("PARKING TICKET"))
|
|
|
- write(BoldOffCmd)
|
|
|
- write(NormalCmd)
|
|
|
- write(ESCPOS_Text(""))
|
|
|
- write(ESCPOS_Text(lotName))
|
|
|
- if len(lotName) > 32 {
|
|
|
- write(FontBCmd)
|
|
|
- write(AlignCenterCmd)
|
|
|
- write(ESCPOS_Text(lotName))
|
|
|
- write(NormalCmd)
|
|
|
- }
|
|
|
- write(ESCPOS_Text("A-General Car"))
|
|
|
- write(ESCPOS_Text(""))
|
|
|
- write(ESCPOS_Text("PARK AT YOUR OWN RISK"))
|
|
|
- write(ESCPOS_Text(line32))
|
|
|
+ write(BoldOffCmd); write(NormalCmd)
|
|
|
+ write(ESCPOS_Text("")); write(ESCPOS_Text(lotName))
|
|
|
+ write(ESCPOS_Text("A-General Car")); write(ESCPOS_Text(""))
|
|
|
+ write(ESCPOS_Text("PARK AT YOUR OWN RISK")); write(ESCPOS_Text(line32))
|
|
|
write(AlignLeftCmd)
|
|
|
- write(ESCPOS_Text("In-Time::" + now))
|
|
|
- if channelCode != "" {
|
|
|
- write(ESCPOS_Text("InGate::" + channelCode))
|
|
|
- }
|
|
|
- if plateNo != "" {
|
|
|
- write(ESCPOS_Text("Veh No::" + plateNo))
|
|
|
- }
|
|
|
- write(ESCPOS_Text(line32))
|
|
|
- write(ESCPOS_Text("Slip No::" + slipNo))
|
|
|
- write(ESCPOS_Text(line32))
|
|
|
- write(AlignCenterCmd)
|
|
|
- write(ESCPOS_Text(""))
|
|
|
- write(ESCPOS_QRCode(ticketNo))
|
|
|
- write(ESCPOS_Text(""))
|
|
|
+ write(ESCPOS_Text("In-Time::"+now))
|
|
|
+ if channelCode != "" { write(ESCPOS_Text("InGate::"+channelCode)) }
|
|
|
+ if plateNo != "" { write(ESCPOS_Text("Veh No::"+plateNo)) }
|
|
|
+ write(ESCPOS_Text(line32)); write(ESCPOS_Text("Slip No::"+slipNo)); write(ESCPOS_Text(line32))
|
|
|
+ write(AlignCenterCmd); write(ESCPOS_Text(""))
|
|
|
+ write(ESCPOS_QRCode(ticketNo)); write(ESCPOS_Text(""))
|
|
|
write(AlignCenterCmd)
|
|
|
write(ESCPOS_Text("SCAN AND PAY WITH"))
|
|
|
write(ESCPOS_Text("NEW THE CANADIA BANK APP"))
|
|
|
- write(InitCmd)
|
|
|
- write(ESCPOS_Text(""))
|
|
|
- write(ESCPOS_Text(""))
|
|
|
- write(ESCPOS_Text(""))
|
|
|
+ write(InitCmd); write(ESCPOS_Text("")); write(ESCPOS_Text("")); write(ESCPOS_Text(""))
|
|
|
write(CutPaperCmd)
|
|
|
|
|
|
global.GVA_DB.Model(&printer).Update("status", "online")
|