feat: 飞牛NAS成本审核更新 - 新增SKU、更新价格表、清理归档及订单记录,同步auto-check改动

This commit is contained in:
12600k-rog-d4
2026-08-27 00:44:44 +08:00
parent bde60dbea0
commit a172a9bb5e
82 changed files with 1804 additions and 1180 deletions

View File

@@ -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 2cn=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()