const PRINT_TITLE = "销售标签";
|
|
const escapeHtml = (value) =>
|
String(value ?? "")
|
.replaceAll("&", "&")
|
.replaceAll("<", "<")
|
.replaceAll(">", ">")
|
.replaceAll('"', """)
|
.replaceAll("'", "'");
|
|
const splitByPage = (items, pageSize) => {
|
const list = Array.isArray(items) ? items : [];
|
if (list.length === 0) return [[]];
|
const pages = [];
|
for (let i = 0; i < list.length; i += pageSize) {
|
pages.push(list.slice(i, i + pageSize));
|
}
|
return pages;
|
};
|
|
const buildMainSpec = (item) => {
|
const value =
|
item?.specificationModel ??
|
item?.productSpecModel ??
|
item?.productName ??
|
"";
|
return String(value ?? "").trim();
|
};
|
|
const buildDetailSpec = (item) => {
|
const value =
|
item?.specification ??
|
item?.spec ??
|
item?.sizeSpec ??
|
item?.productSpec ??
|
"";
|
return String(value ?? "").trim();
|
};
|
|
// 根据文本长度动态计算字体大小
|
const getFontSize = (text, baseSize, maxWidthChars) => {
|
const len = String(text ?? "").length;
|
if (len <= maxWidthChars) return baseSize;
|
// 超长文本按比例缩小
|
const scale = maxWidthChars / len;
|
const minSize = baseSize * 0.7; // 最小不低于基础大小的70%
|
const calculatedSize = baseSize * scale;
|
return Math.max(calculatedSize, minSize);
|
};
|
|
const renderLabelCard = (item) => {
|
const customer = escapeHtml(item?.customerName);
|
const order = escapeHtml(item?.salesContractNo);
|
const model = escapeHtml(buildMainSpec(item));
|
const spec = escapeHtml(buildDetailSpec(item));
|
const address = escapeHtml(item?.floorCode);
|
|
// 动态计算字体大小(基于50mm宽度,约20-25个字符为正常显示范围)
|
const customerSize = getFontSize(customer, 4.2, 18);
|
const orderSize = getFontSize(order, 4.6, 16);
|
const modelSize = getFontSize(model, 4.0, 22);
|
const specSize = getFontSize(spec, 3.8, 28);
|
const addressSize = getFontSize(address, 3.5, 24);
|
|
return `
|
<div class="label-card">
|
<div class="line customer" style="font-size: ${customerSize}mm;">${customer}</div>
|
<div class="line order" style="font-size: ${orderSize}mm;">${order}</div>
|
<div class="line model" style="font-size: ${modelSize}mm;">${model}</div>
|
<div class="line spec" style="font-size: ${specSize}mm;">${spec}</div>
|
<div class="line address" style="font-size: ${addressSize}mm;">${address}</div>
|
</div>
|
`;
|
};
|
|
export const printSalesLabel = (rawList = []) => {
|
const list = Array.isArray(rawList) ? rawList : [];
|
if (!list.length) {
|
throw new Error("标签数据为空,无法打印");
|
}
|
|
const pageSize = 6; // 2 列 * 3 行(50x40mm)
|
const pages = splitByPage(list, pageSize);
|
|
const printWindow = window.open("", "_blank", "width=1200,height=900");
|
if (!printWindow) {
|
throw new Error("浏览器拦截了弹窗,请允许弹窗后重试");
|
}
|
|
const html = `
|
<!DOCTYPE html>
|
<html>
|
<head>
|
<meta charset="UTF-8" />
|
<title>${PRINT_TITLE}</title>
|
<style>
|
body {
|
margin: 0;
|
padding: 0;
|
font-family: "SimSun", serif;
|
color: #222;
|
}
|
.page {
|
width: 104mm;
|
min-height: 124mm;
|
margin: 0 auto;
|
padding: 1mm;
|
box-sizing: border-box;
|
page-break-after: always;
|
}
|
.page:last-child {
|
page-break-after: auto;
|
}
|
.grid {
|
display: grid;
|
grid-template-columns: repeat(2, 50mm);
|
grid-auto-rows: 40mm;
|
gap: 1mm;
|
justify-content: start;
|
}
|
.label-card {
|
border: 0;
|
border-radius: 0;
|
padding: 2.2mm 2.5mm;
|
width: 50mm;
|
height: 40mm;
|
box-sizing: border-box;
|
display: flex;
|
flex-direction: column;
|
justify-content: flex-start;
|
overflow: hidden;
|
}
|
.line {
|
font-weight: 700;
|
line-height: 1.2;
|
word-break: break-all;
|
margin: 0;
|
white-space: nowrap;
|
overflow: hidden;
|
text-overflow: clip;
|
}
|
.customer {
|
/* 基础 4.2mm,动态调整 */
|
}
|
.order {
|
/* 基础 4.6mm,动态调整 */
|
}
|
.model {
|
/* 基础 4.0mm,动态调整 */
|
}
|
.spec {
|
/* 基础 3.8mm,动态调整 */
|
}
|
.address {
|
/* 基础 3.5mm,动态调整 */
|
}
|
@media print {
|
@page {
|
size: 104mm 124mm;
|
margin: 0;
|
}
|
.page {
|
width: 100%;
|
min-height: 0;
|
margin: 0;
|
padding: 1mm;
|
}
|
}
|
</style>
|
</head>
|
<body>
|
${pages
|
.map(
|
(pageList) => `
|
<div class="page">
|
<div class="grid">
|
${pageList.map((item) => renderLabelCard(item)).join("")}
|
</div>
|
</div>
|
`
|
)
|
.join("")}
|
</body>
|
</html>`;
|
|
printWindow.document.write(html);
|
printWindow.document.close();
|
printWindow.onload = () => {
|
setTimeout(() => {
|
printWindow.focus();
|
printWindow.print();
|
printWindow.close();
|
}, 300);
|
};
|
};
|