feat: 飞牛NAS成本审核更新 - 新增SKU、更新价格表、清理归档及订单记录,同步auto-check改动
This commit is contained in:
@@ -25,6 +25,9 @@ var Printed = make(map[string]string)
|
||||
// Printer 报告打印机
|
||||
type Printer interface {
|
||||
Print(text string) error
|
||||
// PrintQR 在打印流末尾追加二维码(ESC/POS GS ( k 指令)
|
||||
// 后端不支持时返回 nil(不打印二维码)
|
||||
PrintQR(url string) error
|
||||
Close() error
|
||||
}
|
||||
|
||||
@@ -66,6 +69,63 @@ func writeEscpos(w io.Writer, text string) error {
|
||||
return bw.Flush()
|
||||
}
|
||||
|
||||
// ============================
|
||||
// ESC/POS 二维码(GS ( k 指令)
|
||||
// ============================
|
||||
//
|
||||
// 适配 EPSON / Star / 芯烨(Xprinter) / 佳博 等主流 ESC/POS 热敏打印机。
|
||||
// 指令格式:GS ( k pL pH cn fn [n...]
|
||||
// cn = 49 (0x31) QR Code
|
||||
// fn = 65 (A) 选择模型 / 67 (C) 模块大小 / 69 (E) 纠错 / 80 (P) 数据 / 81 (Q) 打印
|
||||
//
|
||||
// 参考:EPSON TM-T20 QR Code 规范
|
||||
// 数据长度限制(Model 2 + Level M 纠错):URL 场景 < 512 字节完全够用。
|
||||
|
||||
// escposQR 写入 ESC/POS 二维码指令流(不切纸,由调用方决定结尾)
|
||||
// size: 1-16(模块像素数),默认 6
|
||||
// ecc : 48/49/50/51 (L/M/Q/H)
|
||||
func escposQR(w io.Writer, data string, size byte, ecc byte) error {
|
||||
if size < 1 {
|
||||
size = 1
|
||||
}
|
||||
if size > 16 {
|
||||
size = 16
|
||||
}
|
||||
if ecc < 48 || ecc > 51 {
|
||||
ecc = 49 // 默认 M
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
bw := bufio.NewWriter(w)
|
||||
|
||||
// 1) 选择模型:Model 2(cn=49 fn=65 n=50)
|
||||
bw.WriteString("\x1d(k\x04\x00\x31\x41\x32")
|
||||
|
||||
// 2) 模块大小(cn=49 fn=67 n=size)
|
||||
bw.WriteString("\x1d(k\x03\x00\x31\x43")
|
||||
bw.WriteByte(size)
|
||||
|
||||
// 3) 纠错级别(cn=49 fn=69 n=ecc)
|
||||
bw.WriteString("\x1d(k\x03\x00\x31\x45")
|
||||
bw.WriteByte(ecc)
|
||||
|
||||
// 4) 存储数据:GS ( k pL pH 49 80 48 <data>
|
||||
// pL pH = (data_len + 3) 低/高字节
|
||||
pL := byte((len(data) + 3) & 0xff)
|
||||
pH := byte(((len(data) + 3) >> 8) & 0xff)
|
||||
bw.WriteString("\x1d(k")
|
||||
bw.WriteByte(pL)
|
||||
bw.WriteByte(pH)
|
||||
bw.WriteString("\x31\x50\x30")
|
||||
bw.WriteString(data)
|
||||
|
||||
// 5) 打印(cn=49 fn=81 n=48 不叠加文字)
|
||||
bw.WriteString("\x1d(k\x03\x00\x31\x51\x30")
|
||||
|
||||
return bw.Flush()
|
||||
}
|
||||
|
||||
// ============================
|
||||
// 后端实现
|
||||
// ============================
|
||||
@@ -120,6 +180,9 @@ func (p *SystemPrinter) Print(text string) error {
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// PrintQR 系统打印后端无二维码指令能力,no-op
|
||||
func (p *SystemPrinter) PrintQR(url string) error { return nil }
|
||||
|
||||
// Close 系统打印无需关闭
|
||||
func (p *SystemPrinter) Close() error { return nil }
|
||||
|
||||
@@ -147,6 +210,20 @@ func (p *ESCPOSPrinter) Print(text string) error {
|
||||
return writeEscpos(p.conn, text)
|
||||
}
|
||||
|
||||
// PrintQR 发送 ESC/POS 二维码指令到网络打印机
|
||||
// 走纸居中追加一行提示,模块大小 6,纠错级别 M
|
||||
func (p *ESCPOSPrinter) PrintQR(url string) error {
|
||||
if p.conn == nil {
|
||||
return nil
|
||||
}
|
||||
// 居中(ESC a 1)后写一行"扫码查看详细报告",然后发二维码
|
||||
center := "\x1ba\x01———— 扫码查看详细报告 ————\n\x1ba\x00"
|
||||
if _, err := p.conn.Write([]byte(center)); err != nil {
|
||||
return err
|
||||
}
|
||||
return escposQR(p.conn, url, 6, 49)
|
||||
}
|
||||
|
||||
// Close 关闭连接
|
||||
func (p *ESCPOSPrinter) Close() error {
|
||||
if p.conn != nil {
|
||||
@@ -193,6 +270,18 @@ func (p *USBPrinter) Print(text string) error {
|
||||
return writeEscpos(p.dev, text)
|
||||
}
|
||||
|
||||
// PrintQR 发送 ESC/POS 二维码指令到 USB 打印机
|
||||
func (p *USBPrinter) PrintQR(url string) error {
|
||||
if p.dev == nil {
|
||||
return nil
|
||||
}
|
||||
center := "\x1ba\x01———— 扫码查看详细报告 ————\n\x1ba\x00"
|
||||
if _, err := p.dev.Write([]byte(center)); err != nil {
|
||||
return err
|
||||
}
|
||||
return escposQR(p.dev, url, 6, 49)
|
||||
}
|
||||
|
||||
// Close 关闭设备
|
||||
func (p *USBPrinter) Close() error {
|
||||
if p.dev != nil {
|
||||
@@ -226,6 +315,12 @@ func (p *FilePrinter) Print(text string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// PrintQR 文件后端:将"扫码查看详细报告"提示行 + URL 写入文件(便于在文件中复制链接)
|
||||
func (p *FilePrinter) PrintQR(url string) error {
|
||||
_, err := fmt.Fprintf(p.f, "\n———— 扫码查看详细报告 ————\nURL: %s\n\n", url)
|
||||
return err
|
||||
}
|
||||
|
||||
// Close 关闭文件
|
||||
func (p *FilePrinter) Close() error {
|
||||
return p.f.Close()
|
||||
|
||||
Reference in New Issue
Block a user