fix(print): 商品标签改为竖向 20mm×38mm 布局
原设计 4in×2in 横向与实际标签纸不符,导致内容旋转 90°。按实测尺寸重设为竖向 20mm×38mm,重新排布:酒行名顶部深色背景→商品名→QR码→规格/批次/生产日期→联系方式底部。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -30,30 +30,16 @@ Future<void> printProductLabelImpl({
|
||||
}) async {
|
||||
final base64Img = base64Encode(qrBytes);
|
||||
|
||||
final specVal = (spec ?? '').isNotEmpty ? spec! : '—';
|
||||
final seriesVal = (series ?? '').isNotEmpty ? series! : '—';
|
||||
final batchVal = (batchNo ?? '').isNotEmpty ? batchNo! : '—';
|
||||
final dateVal = (productionDate ?? '').isNotEmpty
|
||||
final specVal = (spec ?? '').isNotEmpty ? spec! : '—';
|
||||
final batchVal = (batchNo ?? '').isNotEmpty ? batchNo! : '—';
|
||||
final dateVal = (productionDate ?? '').isNotEmpty
|
||||
? (productionDate!.length > 10 ? productionDate.substring(0, 10) : productionDate)
|
||||
: '—';
|
||||
|
||||
final footerContact = [
|
||||
if (shopAddress.isNotEmpty) shopAddress,
|
||||
final contactLine = [
|
||||
if (shopPhone.isNotEmpty) shopPhone,
|
||||
].join(' · ');
|
||||
|
||||
// 标签生成时间
|
||||
final now = DateTime.now();
|
||||
final genTime =
|
||||
'${now.year}-${now.month.toString().padLeft(2,'0')}-${now.day.toString().padLeft(2,'0')}'
|
||||
' ${now.hour.toString().padLeft(2,'0')}:${now.minute.toString().padLeft(2,'0')}';
|
||||
|
||||
final remarkRow = (remark ?? '').isNotEmpty
|
||||
? '''<div class="spec-row">
|
||||
<span class="lbl">备 注</span>
|
||||
<span class="val-full">$remark</span>
|
||||
</div>'''
|
||||
: '';
|
||||
if (shopAddress.isNotEmpty) shopAddress,
|
||||
].join(' ');
|
||||
|
||||
final html = '''<!DOCTYPE html>
|
||||
<html>
|
||||
@@ -62,79 +48,71 @@ Future<void> printProductLabelImpl({
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&family=Noto+Serif+SC:wght@700&family=IBM+Plex+Mono:wght@400&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
@page { size: 4in 2in; margin: 0; }
|
||||
/* 标签尺寸:20mm × 38mm,竖向 */
|
||||
@page { size: 20mm 38mm; margin: 0; }
|
||||
* { box-sizing: border-box; margin: 0; padding: 0;
|
||||
-webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
body { width: 4in; height: 2in; overflow: hidden; background: #fff; }
|
||||
body { width: 20mm; height: 38mm; overflow: hidden; background: #fff; }
|
||||
|
||||
.label {
|
||||
width: 4in; height: 2in;
|
||||
display: grid; grid-template-rows: 42px 1fr 18px;
|
||||
width: 20mm; height: 38mm;
|
||||
display: flex; flex-direction: column;
|
||||
font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
/* ── Header:酒行名称 ── */
|
||||
/* ── Header:酒行名称 5.5mm ── */
|
||||
.hdr {
|
||||
background: #1f2a3a; color: #f4ecd8;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 0 15px; overflow: hidden;
|
||||
height: 5.5mm; flex-shrink: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: 0 1mm; overflow: hidden;
|
||||
}
|
||||
.hdr-name {
|
||||
font-family: "Noto Serif SC", serif;
|
||||
font-weight: 700; font-size: 17px; letter-spacing: 0.08em;
|
||||
font-size: 6pt; font-weight: 700; letter-spacing: 0.06em;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.hdr-tag {
|
||||
font-size: 6.5px; letter-spacing: 0.2em; opacity: 0.8;
|
||||
font-style: italic; white-space: nowrap; flex-shrink: 0; padding-left: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ── Body ── */
|
||||
.body {
|
||||
background: #fff; padding: 9px 15px 8px;
|
||||
display: grid; grid-template-columns: 1fr 76px; gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 商品名 */
|
||||
/* ── 商品名 7mm ── */
|
||||
.product-name {
|
||||
font-family: "Noto Serif SC", serif;
|
||||
font-weight: 700; font-size: 13px; letter-spacing: 0.04em;
|
||||
margin-bottom: 7px;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
height: 7mm; flex-shrink: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: 0 1mm;
|
||||
font-size: 7pt; font-weight: 700; letter-spacing: 0.03em;
|
||||
text-align: center; line-height: 1.2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 规格行 */
|
||||
/* ── QR 码区 15mm ── */
|
||||
.qr-wrap {
|
||||
height: 15mm; flex-shrink: 0;
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center; gap: 0.5mm;
|
||||
}
|
||||
.qr-wrap img { width: 13.5mm; height: 13.5mm; object-fit: contain; }
|
||||
.qr-cap { font-size: 4pt; color: #888; letter-spacing: 0.12em; }
|
||||
|
||||
/* ── 规格/批次 7.5mm ── */
|
||||
.specs {
|
||||
flex: 1; padding: 0.5mm 1.5mm;
|
||||
display: flex; flex-direction: column; justify-content: center; gap: 0.8mm;
|
||||
}
|
||||
.spec-row {
|
||||
display: flex; gap: 6px; align-items: baseline;
|
||||
font-size: 6.5px; margin-bottom: 3.5px; flex-wrap: nowrap;
|
||||
display: flex; gap: 1mm; align-items: baseline;
|
||||
font-size: 5pt; white-space: nowrap; overflow: hidden;
|
||||
}
|
||||
.lbl { color: #888; letter-spacing: 0.1em; white-space: nowrap; flex-shrink: 0; }
|
||||
.lbl { color: #888; flex-shrink: 0; }
|
||||
.val { font-family: "IBM Plex Mono", monospace;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.val-full { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
color: #444; font-size: 6px; }
|
||||
overflow: hidden; text-overflow: ellipsis; }
|
||||
|
||||
/* 同行双字段 */
|
||||
.spec-row-2 {
|
||||
display: grid; grid-template-columns: 28px 1fr 28px 1fr;
|
||||
gap: 0 7px; font-size: 6.5px; margin-bottom: 3.5px;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
/* QR */
|
||||
.qr-col { display: flex; flex-direction: column; align-items: center; gap: 3px; }
|
||||
.qr-col img { width: 68px; height: 68px; object-fit: contain; display: block; }
|
||||
.qr-cap { font-size: 5px; letter-spacing: 0.2em; color: #666; text-align: center; }
|
||||
|
||||
/* ── Footer:地址 + 生成时间 ── */
|
||||
/* ── Footer:联系方式 3mm ── */
|
||||
.ftr {
|
||||
background: #f4ecd8;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 0 15px;
|
||||
font-family: "IBM Plex Mono", monospace;
|
||||
font-size: 5px; color: #5a4e35; letter-spacing: 0.04em; overflow: hidden;
|
||||
background: #f4ecd8; height: 3mm; flex-shrink: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: 0 1mm;
|
||||
font-size: 4pt; color: #5a4e35; overflow: hidden; white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -143,41 +121,23 @@ body { width: 4in; height: 2in; overflow: hidden; background: #fff; }
|
||||
|
||||
<div class="hdr">
|
||||
<span class="hdr-name">$shopName</span>
|
||||
<span class="hdr-tag">Certificate of Authenticity</span>
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
<div>
|
||||
<div class="product-name">$name</div>
|
||||
<div class="product-name">$name</div>
|
||||
|
||||
<div class="spec-row-2">
|
||||
<span class="lbl">规 格</span>
|
||||
<span class="val">$specVal</span>
|
||||
<span class="lbl">系 列</span>
|
||||
<span class="val">$seriesVal</span>
|
||||
</div>
|
||||
|
||||
<div class="spec-row-2">
|
||||
<span class="lbl">批 号</span>
|
||||
<span class="val">$batchVal</span>
|
||||
<span class="lbl">生产日期</span>
|
||||
<span class="val">$dateVal</span>
|
||||
</div>
|
||||
|
||||
$remarkRow
|
||||
</div>
|
||||
|
||||
<div class="qr-col">
|
||||
<img src="data:image/png;base64,$base64Img" />
|
||||
<div class="qr-cap">扫码溯源 · TRACE</div>
|
||||
</div>
|
||||
<div class="qr-wrap">
|
||||
<img src="data:image/png;base64,$base64Img" />
|
||||
<div class="qr-cap">扫码溯源</div>
|
||||
</div>
|
||||
|
||||
<div class="ftr">
|
||||
<span>${footerContact.isNotEmpty ? footerContact : shopName}</span>
|
||||
<span>$genTime</span>
|
||||
<div class="specs">
|
||||
<div class="spec-row"><span class="lbl">规</span><span class="val">$specVal</span></div>
|
||||
<div class="spec-row"><span class="lbl">批</span><span class="val">$batchVal</span></div>
|
||||
<div class="spec-row"><span class="lbl">产</span><span class="val">$dateVal</span></div>
|
||||
</div>
|
||||
|
||||
<div class="ftr">${contactLine.isNotEmpty ? contactLine : shopName}</div>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
if (document.fonts && document.fonts.ready) {
|
||||
|
||||
Reference in New Issue
Block a user