diff --git a/client/lib/core/utils/print_util_stub.dart b/client/lib/core/utils/print_util_stub.dart index 0ce3502..d6f225d 100644 --- a/client/lib/core/utils/print_util_stub.dart +++ b/client/lib/core/utils/print_util_stub.dart @@ -47,8 +47,8 @@ String _fileTs() { // ── 设计色彩 token ────────────────────────────────────────────────────────── const _navy = PdfColor(0.122, 0.165, 0.227); // #1F2A3A header/chip -const _cream = PdfColor(0.957, 0.925, 0.847); // #F4ECD8 footer/reversed text -const _footnote = PdfColor(0.353, 0.306, 0.208); // #5A4E35 footer text +const _cream = PdfColor(0.957, 0.925, 0.847); // #F4ECD8 抬头反白店名 +const _footnote = PdfColor(0.353, 0.306, 0.208); // #5A4E35 编号 / 三字段小字 const _ink = PdfColor(0.067, 0.067, 0.067); // #111 body text // ── 热敏标签 TSPL 裸发(桌面端:dart:ui 画扁平标签位图 → BITMAP → lp -o raw)──────── @@ -253,10 +253,9 @@ Future _renderLabelBitmap({ // 热敏机为单色介质,实际打印时头/脚颜色会退化为黑白(TSPL 路径另行处理)。 const cWhite = ui.Color(0xFFFFFFFF); // ds-ignore const cNavy = ui.Color(0xFF1F2A3A); // ds-ignore 深蓝店名头 - const cCream = ui.Color(0xFFF4ECD8); // ds-ignore 米色页脚 / 头部字色 + const cCream = ui.Color(0xFFF4ECD8); // ds-ignore 抬头店名字色 const cInk = ui.Color(0xFF111111); // ds-ignore 正文 const cCode = ui.Color(0xFF333333); // ds-ignore 编号 / 三字段 - const cFoot = ui.Color(0xFF5A4E35); // ds-ignore 页脚字 canvas.drawRect(ui.Rect.fromLTWH(0, 0, w.toDouble(), h.toDouble()), ui.Paint()..color = cWhite); @@ -267,19 +266,9 @@ Future _renderLabelBitmap({ ui.Rect.fromLTWH(0, 0, w.toDouble(), headerH), ui.Paint()..color = cNavy); _drawText(canvas, shop, 10, 5, 12, w - 20, bold: true, color: cCream); - // ── 米色页脚 ──────────────────────────────────────────────── - const footerH = 15.0; - const footerTop = h - footerH; // 145 - canvas.drawRect(ui.Rect.fromLTWH(0, footerTop, w.toDouble(), footerH), - ui.Paint()..color = cCream); - // 页脚只留右侧尺寸标注:店名已在顶部抬头,页脚不再重复(2026-08-27 去冗余) - final szW = _measureWidth('40×20mm', 8, false); - _drawText(canvas, '40×20mm', w - 10 - szW, footerTop + 3.5, 8, szW, - color: cFoot); - - // ── 主体两列布局 ──────────────────────────────────────────── + // ── 主体两列布局(无页脚:主体直抵纸底,2026-08-27 删掉底部米色尺寸条)──────── const bodyTop = headerH; // 24 - const bodyBot = footerTop; // 145 + const double bodyBot = 160.0; // 直抵纸底 h(原到页脚顶 145),二维码/条码顺势放大 const padV = 6.0, padH = 8.0; // 收紧留白,给二维码腾空间 const double colGap = 6.0; // 左列与二维码列间距(原 10,收小) @@ -384,7 +373,7 @@ Future _renderLabelBitmap({ /// 桌面端把整张标签「光栅化」成单色位图裸发到热敏机(TSPL BITMAP),令热敏输出与 /// 预览画布 100% 一致——彻底消除内置点阵字(TSS16/24)与预览 TrueType 度量不一致 -/// 导致的字体重叠 / 失真。文字/抬头/页脚走光栅;条码(Code128)与二维码仍走原生 +/// 导致的字体重叠 / 失真。文字/抬头走光栅;条码(Code128)与二维码仍走原生 /// BARCODE / BITMAP 命令保证扫码可靠(光栅化后细条/密码易糊)。 /// 检测不到热敏机 -> 返回 false(交系统打印);检测到则强制 TSPL,失败抛异常。 /// [printerName] 非空时跳过自动检测直接使用,为空则走 _findThermalPrinter()。 @@ -404,7 +393,7 @@ Future _printFlatLabelThermal({ const w = 320, h = 160; // 40×20mm @203dpi(逻辑尺寸) const wBytes = (w + 7) >> 3; // 40 bytes/row - // ── 文字/抬头/页脚整幅光栅:复用预览画布(跳过条码+QR,二者改原生命令)───────── + // ── 文字/抬头整幅光栅:复用预览画布(跳过条码+QR,二者改原生命令)───────── // 画布内部 2× 超采样(640×320),此处 2×2 盒式降采样 + 亮度 128 阈值二值化,边缘更干净。 final img = await _renderLabelBitmap( shop: shop, @@ -425,7 +414,7 @@ Future _printFlatLabelThermal({ 'REFERENCE 0,0\r\nDENSITY 10\r\nSPEED 2\r\nCLS\r\n', )); - // 整幅文字位图(mode 0 覆写整版):深蓝抬头→黑底反白、米色页脚→白底黑字, + // 整幅文字位图(mode 0 覆写整版):深蓝抬头→黑底反白,其余白底黑字, // 均由亮度阈值自然还原,无需 REVERSE;bit 0=黑点,默认 0xFF=白。 buf.add(ascii.encode('BITMAP 0,0,$wBytes,$h,0,')); for (int y = 0; y < h; y++) { @@ -449,10 +438,10 @@ Future _printFlatLabelThermal({ buf.add(ascii.encode('\r\n')); // ── 右列二维码(原生 BITMAP,避免光栅降采样糊码):占主体整高、右对齐 ── - const qrW = 104, qrH = 104; - const qrX = 320 - 8 - qrW; // 208 - const bodyTop = 26, bodyBot = 134; - const qrY = bodyTop + ((bodyBot - bodyTop) - qrH) ~/ 2; // 28 + const qrW = 118, qrH = 118; + const qrX = 320 - 8 - qrW; // 194 + const bodyTop = 24, bodyBot = 160; // 无页脚:主体直抵纸底 + const qrY = bodyTop + ((bodyBot - bodyTop) - qrH) ~/ 2; // 33 const qrWBytes = (qrW + 7) >> 3; // 13 final qrCodec = await ui.instantiateImageCodec(qrBytes, targetWidth: qrW, targetHeight: qrH); @@ -475,9 +464,9 @@ Future _printFlatLabelThermal({ buf.add(ascii.encode('\r\n')); // ── 左列底部整幅一维条码(原生 BARCODE,Code128,内容=商品编号),narrow 自适应铺满居中 ── - const leftX = 8, leftRight = qrX - 6, leftW = leftRight - leftX; // 8..202, 194 - const kBarH = 28; - const kBarY = bodyBot - 4 - kBarH; // 102 + const leftX = 8, leftRight = qrX - 6, leftW = leftRight - leftX; // 8..188, 180 + const kBarH = 34; + const kBarY = bodyBot - 8 - kBarH; // 118 if (code.isNotEmpty) { final estModules = 11 * code.length + 35; // Code128B 估算模块数(含起止校验) final narrow = (leftW / estModules).floor().clamp(2, 4); @@ -518,7 +507,6 @@ Future printProductLabelImpl({ const labelW = 40.0 * PdfPageFormat.mm; const labelH = 20.0 * PdfPageFormat.mm; const headerH = labelH * 0.20; - const footerH = labelH * 0.11; // 底部平铺三字段:度数(型号) / 规格(版本) / 日期(口径与预览、TSPL 一致) final subs = _labelSubFields(series, spec, productionDate); @@ -653,22 +641,6 @@ Future printProductLabelImpl({ ), ), ), - - // ── Footer:米色页脚(仅尺寸;店名已在抬头,不再重复)───────────────── - pw.Container( - height: footerH, - color: _cream, - padding: const pw.EdgeInsets.symmetric(horizontal: 5), - child: pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.end, - crossAxisAlignment: pw.CrossAxisAlignment.center, - children: [ - pw.Text('40×20mm', - style: pw.TextStyle( - font: font, fontSize: 3.5, color: _footnote)), - ], - ), - ), ], ), )); diff --git a/client/lib/core/utils/print_util_web.dart b/client/lib/core/utils/print_util_web.dart index dbd6195..7c96a17 100644 --- a/client/lib/core/utils/print_util_web.dart +++ b/client/lib/core/utils/print_util_web.dart @@ -116,14 +116,6 @@ body { width: 40mm; height: 20mm; overflow: hidden; background: #fff; } /* 右:二维码占主体整高(正方形)*/ .qr { flex-shrink: 0; height: 100%; aspect-ratio: 1; } .qr img { width: 100%; height: 100%; object-fit: contain; display: block; } - -/* ── Footer:米色页脚(仅尺寸;店名已在抬头,不再重复)── */ -.ftr { - background: #f4ecd8; height: 2.4mm; flex-shrink: 0; - display: flex; align-items: center; justify-content: space-between; - padding: 0 1.2mm; - font-size: 3.4pt; color: #5a4e35; overflow: hidden; white-space: nowrap; -} @@ -146,8 +138,6 @@ body { width: 40mm; height: 20mm; overflow: hidden; background: #fff; } -
40×20mm
-